{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2024机器智能 实验二"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# File: 2024机器智能实验02_teacher.ipynb\n",
    "# License: MIT License \n",
    "# Copyright: (c) 2024 Rongxi Li <lirx67@mail2.sysu.edu.cn> \n",
    "# Created: 2024-02-27\n",
    "# Brief: 2024机器智能实验课教师版——实验二"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 必要依赖"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Defaulting to user installation because normal site-packages is not writeable\n",
      "Requirement already satisfied: ipympl in c:\\programdata\\miniconda3\\lib\\site-packages (0.9.3)\n",
      "Requirement already satisfied: ipython<9 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipympl) (8.22.1)\n",
      "Requirement already satisfied: numpy in c:\\programdata\\miniconda3\\lib\\site-packages (from ipympl) (1.26.4)\n",
      "Requirement already satisfied: ipython-genutils in c:\\programdata\\miniconda3\\lib\\site-packages (from ipympl) (0.2.0)\n",
      "Requirement already satisfied: pillow in c:\\programdata\\miniconda3\\lib\\site-packages (from ipympl) (10.2.0)\n",
      "Requirement already satisfied: traitlets<6 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipympl) (5.14.1)\n",
      "Requirement already satisfied: ipywidgets<9,>=7.6.0 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipympl) (8.1.2)\n",
      "Requirement already satisfied: matplotlib<4,>=3.4.0 in c:\\programdata\\miniconda3\\lib\\site-packages (from ipympl) (3.8.3)\n",
      "Requirement already satisfied: decorator in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipython<9->ipympl) (5.1.1)\n",
      "Requirement already satisfied: jedi>=0.16 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipython<9->ipympl) (0.19.1)\n",
      "Requirement already satisfied: matplotlib-inline in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipython<9->ipympl) (0.1.6)\n",
      "Requirement already satisfied: prompt-toolkit<3.1.0,>=3.0.41 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipython<9->ipympl) (3.0.43)\n",
      "Requirement already satisfied: pygments>=2.4.0 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipython<9->ipympl) (2.17.2)\n",
      "Requirement already satisfied: stack-data in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipython<9->ipympl) (0.6.3)\n",
      "Requirement already satisfied: colorama in c:\\programdata\\miniconda3\\lib\\site-packages (from ipython<9->ipympl) (0.4.4)\n",
      "Requirement already satisfied: comm>=0.1.3 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipywidgets<9,>=7.6.0->ipympl) (0.2.1)\n",
      "Requirement already satisfied: widgetsnbextension~=4.0.10 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipywidgets<9,>=7.6.0->ipympl) (4.0.10)\n",
      "Requirement already satisfied: jupyterlab-widgets~=3.0.10 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from ipywidgets<9,>=7.6.0->ipympl) (3.0.10)\n",
      "Requirement already satisfied: contourpy>=1.0.1 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib<4,>=3.4.0->ipympl) (1.2.0)\n",
      "Requirement already satisfied: cycler>=0.10 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib<4,>=3.4.0->ipympl) (0.12.1)\n",
      "Requirement already satisfied: fonttools>=4.22.0 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib<4,>=3.4.0->ipympl) (4.49.0)\n",
      "Requirement already satisfied: kiwisolver>=1.3.1 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib<4,>=3.4.0->ipympl) (1.4.5)\n",
      "Requirement already satisfied: packaging>=20.0 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib<4,>=3.4.0->ipympl) (23.0)\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib<4,>=3.4.0->ipympl) (3.1.1)\n",
      "Requirement already satisfied: python-dateutil>=2.7 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from matplotlib<4,>=3.4.0->ipympl) (2.8.2)\n",
      "Requirement already satisfied: parso<0.9.0,>=0.8.3 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from jedi>=0.16->ipython<9->ipympl) (0.8.3)\n",
      "Requirement already satisfied: wcwidth in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from prompt-toolkit<3.1.0,>=3.0.41->ipython<9->ipympl) (0.2.13)\n",
      "Requirement already satisfied: six>=1.5 in c:\\programdata\\miniconda3\\lib\\site-packages (from python-dateutil>=2.7->matplotlib<4,>=3.4.0->ipympl) (1.16.0)\n",
      "Requirement already satisfied: executing>=1.2.0 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from stack-data->ipython<9->ipympl) (2.0.1)\n",
      "Requirement already satisfied: asttokens>=2.1.0 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from stack-data->ipython<9->ipympl) (2.4.1)\n",
      "Requirement already satisfied: pure-eval in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from stack-data->ipython<9->ipympl) (0.2.2)\n",
      "Defaulting to user installation because normal site-packages is not writeable\n",
      "Requirement already satisfied: numpy in c:\\programdata\\miniconda3\\lib\\site-packages (1.26.4)\n",
      "Defaulting to user installation because normal site-packages is not writeable\n",
      "Requirement already satisfied: matplotlib in c:\\programdata\\miniconda3\\lib\\site-packages (3.8.3)\n",
      "Requirement already satisfied: contourpy>=1.0.1 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (1.2.0)\n",
      "Requirement already satisfied: cycler>=0.10 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (0.12.1)\n",
      "Requirement already satisfied: fonttools>=4.22.0 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (4.49.0)\n",
      "Requirement already satisfied: kiwisolver>=1.3.1 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (1.4.5)\n",
      "Requirement already satisfied: numpy<2,>=1.21 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (1.26.4)\n",
      "Requirement already satisfied: packaging>=20.0 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (23.0)\n",
      "Requirement already satisfied: pillow>=8 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (10.2.0)\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in c:\\programdata\\miniconda3\\lib\\site-packages (from matplotlib) (3.1.1)\n",
      "Requirement already satisfied: python-dateutil>=2.7 in c:\\users\\jungh\\appdata\\roaming\\python\\python311\\site-packages (from matplotlib) (2.8.2)\n",
      "Requirement already satisfied: six>=1.5 in c:\\programdata\\miniconda3\\lib\\site-packages (from python-dateutil>=2.7->matplotlib) (1.16.0)\n"
     ]
    }
   ],
   "source": [
    "!pip install --upgrade ipympl\n",
    "!pip install numpy \n",
    "!pip install matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib ipympl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import math\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib as mpl\n",
    "import matplotlib.animation as animation\n",
    "from collections import defaultdict\n",
    "import heapq\n",
    "import pickle\n",
    "from typing import List, Tuple, Dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "from IPython.display import Image, display\n",
    "\n",
    "\n",
    "def mm(graph):\n",
    "    graphbytes = graph.encode(\"utf8\")\n",
    "    base64_bytes = base64.b64encode(graphbytes)\n",
    "    base64_string = base64_bytes.decode(\"ascii\")\n",
    "    display(Image(url=\"https://mermaid.ink/img/\" + base64_string + \"?bgColor=FFFFFF\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "class PriorityQueue:\n",
    "    def __init__(self):\n",
    "        self._heap = []\n",
    "        self._count = 0\n",
    "\n",
    "    def put(self, item, priority):\n",
    "        heapq.heappush(self._heap, (priority, self._count, item))\n",
    "        self._count += 1\n",
    "\n",
    "    def get(self):\n",
    "        return heapq.heappop(self._heap)[2]\n",
    "\n",
    "    def empty(self):\n",
    "        return len(self._heap) == 0\n",
    "\n",
    "    @property\n",
    "    def data(self):\n",
    "        return (i for _, _, i in self._heap)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 启发式搜索"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.1 Dijkstra算法（先不做）\n",
    "下图是有权图，其权重表示这两个节点之间的代价。请使用Dijkstra算法对下面有权图搜索任意两点的最优路径，并给出该路径的总代价。\n",
    "\n",
    "* 算法输入输出要求：\n",
    "  * 输入：图；起始点；终点。\n",
    "  * 输出：路径；路径长度。\n",
    "\n",
    "* 例：\n",
    "  * 起始点D，终点J：(['D', 'A', 'B', 'F', 'K', 'J'], 15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "_kg_hide-input": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<img src=\"https://mermaid.ink/img/CmdyYXBoIFRECiAgICBBIC0tIDUgLS0tIEI7CiAgICBBIC0tIDMgLS0tIEM7CiAgICBBIC0tIDIgLS0tIEQ7CiAgICBCIC0tIDggLS0tIEM7CiAgICBCIC0tIDQgLS0tIEU7CiAgICBCIC0tIDEgLS0tIEY7CiAgICBDIC0tIDkgLS0tIEc7CiAgICBEIC0tIDcgLS0tIEg7CiAgICBEIC0tIDEyIC0tLSBJOwogICAgRSAtLSA1IC0tLSBKOwogICAgRiAtLSAxNCAtLS0gSjsKICAgIEYgLS0gMyAtLS0gSzsKICAgIEYgLS0gMSAtLS0gTDsKICAgIEcgLS0gMiAtLS0gSDsKICAgIEcgLS0gMSAtLS0gTDsKICAgIEcgLS0gMSAtLS0gTTsKICAgIEkgLS0gNCAtLS0gTTsKICAgIEogLS0gNCAtLS0gSzsK?bgColor=FFFFFF\"/>"
      ],
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mm(\n",
    "    \"\"\"\n",
    "graph TD\n",
    "    A -- 5 --- B;\n",
    "    A -- 3 --- C;\n",
    "    A -- 2 --- D;\n",
    "    B -- 8 --- C;\n",
    "    B -- 4 --- E;\n",
    "    B -- 1 --- F;\n",
    "    C -- 9 --- G;\n",
    "    D -- 7 --- H;\n",
    "    D -- 12 --- I;\n",
    "    E -- 5 --- J;\n",
    "    F -- 14 --- J;\n",
    "    F -- 3 --- K;\n",
    "    F -- 1 --- L;\n",
    "    G -- 2 --- H;\n",
    "    G -- 1 --- L;\n",
    "    G -- 1 --- M;\n",
    "    I -- 4 --- M;\n",
    "    J -- 4 --- K;\n",
    "\"\"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2. 邻接表\n",
    "class AdjacencyMapGraph:\n",
    "    def __init__(self, edges: List[Tuple[str, str]], weight: List[float] = None):\n",
    "        self.adjacency_map = defaultdict(list)\n",
    "        self.weight_map = {}\n",
    "        self.add_bi_edges(edges, weight)\n",
    "\n",
    "    def add_bi_edges(self, edges: List[Tuple[str, str]], weight: List[float] = None):\n",
    "        if weight is not None:\n",
    "            assert len(edges) == len(weight)\n",
    "        for i, edge in enumerate(edges):\n",
    "            node1, node2 = edge\n",
    "            if not self.adjacency_map.get(node1) or node2 not in self.adjacency_map.get(\n",
    "                node1\n",
    "            ):\n",
    "                self.adjacency_map[node1].append(node2)\n",
    "                self.adjacency_map[node2].append(node1)\n",
    "                self.weight_map[(node1, node2)] = 1 if weight is None else weight[i]\n",
    "                self.weight_map[(node2, node1)] = 1 if weight is None else weight[i]\n",
    "\n",
    "    def get_neighbors(self, node):\n",
    "        return self.adjacency_map[node]\n",
    "\n",
    "    def get_cost(self, node1: str, node2: str):\n",
    "        ret = self.weight_map.get((node1, node2))\n",
    "        if ret is None:\n",
    "            return float(\"inf\")\n",
    "        else:\n",
    "            return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "edges = [\n",
    "    (\"A\", \"B\"),\n",
    "    (\"A\", \"C\"),\n",
    "    (\"A\", \"D\"),\n",
    "    (\"B\", \"C\"),\n",
    "    (\"B\", \"E\"),\n",
    "    (\"B\", \"F\"),\n",
    "    (\"C\", \"G\"),\n",
    "    (\"D\", \"H\"),\n",
    "    (\"D\", \"I\"),\n",
    "    (\"E\", \"J\"),\n",
    "    (\"F\", \"J\"),\n",
    "    (\"F\", \"K\"),\n",
    "    (\"F\", \"L\"),\n",
    "    (\"G\", \"H\"),\n",
    "    (\"G\", \"L\"),\n",
    "    (\"G\", \"M\"),\n",
    "    (\"I\", \"M\"),\n",
    "    (\"J\", \"K\"),\n",
    "]\n",
    "costs = [5, 3, 2, 8, 4, 1, 9, 7, 12, 5, 14, 3, 1, 2, 1, 1, 4, 4]\n",
    "graph = AdjacencyMapGraph(edges, costs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**请在此完成Dijkstra算法**\n",
    "\n",
    "提示：建议使用`PriorityQueue`完成。PriorityQueue 是一种数据结构，它允许存储具有优先级的元素，并根据优先级确定元素的顺序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def dijkstra(graph, start: str, dest: str):\n",
    "    # TODO\n",
    "    return [], 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "([], 0)\n"
     ]
    }
   ],
   "source": [
    "print(dijkstra(graph, \"D\", \"J\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 答案\n",
    "def dijkstra(graph, start: str, dest: str):\n",
    "    queue = PriorityQueue()\n",
    "    cost_so_far: Dict[str, float] = {}\n",
    "    came_from: Dict[str, str] = {}\n",
    "    path = []\n",
    "    queue.put(start, 0)\n",
    "    cost_so_far[start] = 0\n",
    "\n",
    "    while not queue.empty():\n",
    "        current = queue.get()\n",
    "        print(\"search:\", current)\n",
    "        if current == dest:\n",
    "            break\n",
    "        for next in graph.get_neighbors(current):\n",
    "            new_cost = cost_so_far[current] + graph.get_cost(current, next)\n",
    "            if next not in cost_so_far or new_cost < cost_so_far[next]:\n",
    "                priority = new_cost\n",
    "                queue.put(next, priority)\n",
    "                cost_so_far[next] = new_cost\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not cost_so_far.get(dest):\n",
    "        return [], 0\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1], cost_so_far.get(dest)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "search: D\n",
      "search: A\n",
      "search: C\n",
      "search: H\n",
      "search: B\n",
      "search: F\n",
      "search: G\n",
      "search: L\n",
      "search: M\n",
      "search: E\n",
      "search: K\n",
      "search: I\n",
      "search: G\n",
      "search: J\n",
      "(['D', 'A', 'B', 'F', 'K', 'J'], 15)\n"
     ]
    }
   ],
   "source": [
    "print(dijkstra(graph, \"D\", \"J\"))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2 八数码问题（一）\n",
    "请用启发式搜索算法求解以下八数码问题。\n",
    "\n",
    "请尝试采用以下两种启发函数：\n",
    "1. h(n)=0\n",
    "2. h(n)=“不在位”的将牌数\n",
    "\n",
    "参考答案\n",
    "\n",
    "```\n",
    "[((2, 8, 3), (1, 6, 4), (7, 0, 5)),\n",
    " ((2, 8, 3), (1, 0, 4), (7, 6, 5)),\n",
    " ((2, 0, 3), (1, 8, 4), (7, 6, 5)),\n",
    " ((0, 2, 3), (1, 8, 4), (7, 6, 5)),\n",
    " ((1, 2, 3), (0, 8, 4), (7, 6, 5)),\n",
    " ((1, 2, 3), (8, 0, 4), (7, 6, 5))]\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "dff19f7fe19a431c865883f931af74d2",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    2.2\n",
       "                </div>\n",
       "                <img src='' width=200.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## 打印问题图片，不用看\n",
    "data_begin = ((2, 8, 3), (1, 6, 4), (7, \"\", 5))\n",
    "data_end = ((1, 2, 3), (8, \"\", 4), (7, 6, 5))\n",
    "fig, ax = plt.subplots(1, 2, num=\"2.2\", figsize=(2, 2))\n",
    "table = ax[0].table(\n",
    "    cellText=data_begin, loc=\"center\", cellLoc=\"center\", colWidths=[0.3, 0.3, 0.3]\n",
    ")\n",
    "ax[0].axis(\"off\")\n",
    "ax[0].set_title(\"start\")\n",
    "table = ax[1].table(\n",
    "    cellText=data_end, loc=\"center\", cellLoc=\"center\", colWidths=[0.3, 0.3, 0.3]\n",
    ")\n",
    "ax[1].axis(\"off\")\n",
    "ax[1].set_title(\"dest\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**打印八数码图**\n",
    "\n",
    "不用看"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def PlotEightDigit(data: Tuple[Tuple[int]], num=\"EightDigit\"):\n",
    "    fig, ax = plt.subplots(num=num, figsize=(1, 1))\n",
    "    table = ax.table(\n",
    "        cellText=data, loc=\"center\", cellLoc=\"center\", colWidths=[0.3, 0.3, 0.3]\n",
    "    )\n",
    "    ax.axis(\"off\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "start = ((2, 8, 3), (1, 6, 4), (7, 0, 5))\n",
    "# 请参照start填写dest内容\n",
    "dest = ()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 答案\n",
    "start = ((2, 8, 3), (1, 6, 4), (7, 0, 5))\n",
    "dest = ((1, 2, 3), (8, 0, 4), (7, 6, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**启发函数的实现**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def heuristic_none(data: Tuple[Tuple[int]], dest: Tuple[Tuple[int]]):\n",
    "    return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 答案\n",
    "def heuristic_diff(data: Tuple[Tuple[int]], dest: Tuple[Tuple[int]]):\n",
    "    ret = 0\n",
    "    for i in range(len(data)):\n",
    "        for j in range(len(data[0])):\n",
    "            if data[i][j] != dest[i][j]:\n",
    "                ret += 1\n",
    "    return ret\n",
    "\n",
    "\n",
    "def heuristic_dist(data: Tuple[Tuple[int]], dest: Tuple[Tuple[int]]):\n",
    "    data_loc_map = {}\n",
    "    dest_loc_map = {}\n",
    "    ret = 0\n",
    "\n",
    "    for i in range(len(data)):\n",
    "        for j in range(len(data[0])):\n",
    "            data_loc_map[data[i][j]] = (i, j)\n",
    "    for i in range(len(dest)):\n",
    "        for j in range(len(dest[0])):\n",
    "            dest_loc_map[dest[i][j]] = (i, j)\n",
    "\n",
    "    for k in data_loc_map:\n",
    "        ret += sum([abs(a - b) for a, b in zip(data_loc_map[k], dest_loc_map[k])])\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**获取邻居**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 获取当前八数码所有可能的行动\n",
    "def get_neighbors(data: Tuple[Tuple[int]]):\n",
    "    # 此为返回值\n",
    "    ret = []\n",
    "    ## 找到0所在位置\n",
    "\n",
    "    ## 判断该位置四个邻居是否合法（在框内）\n",
    "    ## 若在，构造新的八数码图并添加到返回值中\n",
    "\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 答案\n",
    "def get_exchange(data, p1, p2):\n",
    "    def get_data(x, y):\n",
    "        if x == p1[0] and y == p1[1]:\n",
    "            return data[p2[0]][p2[1]]\n",
    "        elif x == p2[0] and y == p2[1]:\n",
    "            return data[p1[0]][p1[1]]\n",
    "        else:\n",
    "            return data[x][y]\n",
    "\n",
    "    ret = tuple(\n",
    "        tuple((get_data(i, j) for j in range(len(data[0])))) for i in range(len(data))\n",
    "    )\n",
    "    return ret\n",
    "\n",
    "\n",
    "def get_neighbors(data: Tuple[Tuple[int]]):\n",
    "    ret = []\n",
    "    ## 找到0所在位置\n",
    "    zx, zy = None, None\n",
    "    for i in range(len(data)):\n",
    "        for j in range(len(data[0])):\n",
    "            if data[i][j] == 0:\n",
    "                zx, zy = i, j\n",
    "                break\n",
    "    if zx is None:\n",
    "        raise RuntimeError(\"Something went wrong.\")\n",
    "    ## 判断该位置四个邻居是否合法（在框内）\n",
    "    ## 若在，构造新的八数码图并添加到返回值中\n",
    "    neighbors = [(zx + 1, zy), (zx - 1, zy), (zx, zy - 1), (zx, zy + 1)]\n",
    "    for nx, ny in neighbors:\n",
    "        if nx >= 0 and nx < 3 and ny >= 0 and ny < 3:\n",
    "            ret.append(get_exchange(data, (zx, zy), (nx, ny)))\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**PriorityQueue介绍**\n",
    "\n",
    "PriorityQueue是由堆实现的，它具有能够按顺序将插入的数据弹出。\n",
    "\n",
    "其输入第一个参数为数据，第二个参数为优先级。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data2\n",
      "data5\n",
      "data7\n"
     ]
    }
   ],
   "source": [
    "pq_demo = PriorityQueue()\n",
    "pq_demo.put(\"data5\", 5)\n",
    "pq_demo.put(\"data9\", 9)\n",
    "pq_demo.put(\"data2\", 2)\n",
    "pq_demo.put(\"data7\", 7)\n",
    "\n",
    "print(pq_demo.get())\n",
    "print(pq_demo.get())\n",
    "print(pq_demo.get())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**启发式搜索实现**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "def search(start, dest, heuristic):\n",
    "    ## 定义数据\n",
    "    open_list = PriorityQueue()\n",
    "    # ...\n",
    "\n",
    "    ## 开始搜索\n",
    "    while not open_list.empty():\n",
    "        # do something\n",
    "        pass\n",
    "    ## 回溯路径\n",
    "\n",
    "    ## 返回路径\n",
    "    return []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 答案\n",
    "def search(start, dest, heuristic):\n",
    "    open_list = PriorityQueue()\n",
    "    cost_so_far: Dict[str, float] = {}\n",
    "    came_from: Dict[str, str] = {}\n",
    "    path = []\n",
    "    open_list.put(start, 0)\n",
    "    cost_so_far[start] = 0\n",
    "\n",
    "    while not open_list.empty():\n",
    "        current = open_list.get()\n",
    "\n",
    "        if current == dest:\n",
    "            break\n",
    "        for next in get_neighbors(current):\n",
    "            new_cost = cost_so_far[current] + 1\n",
    "            if next not in cost_so_far or new_cost < cost_so_far[next]:\n",
    "                priority = new_cost + heuristic(next, dest)\n",
    "                open_list.put(next, priority)\n",
    "                cost_so_far[next] = new_cost\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not cost_so_far.get(dest):\n",
    "        return []\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "68d2e26eabb84da299e824a5d488b45e",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    fig0\n",
       "                </div>\n",
       "                <img src='' width=100.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6768749626f443c98423e811abe15c6f",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    fig1\n",
       "                </div>\n",
       "                <img src='' width=100.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "87830a905474477fabbdd8865a460152",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    fig2\n",
       "                </div>\n",
       "                <img src='' width=100.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "65c2f8244ae84f61af874b4a2292e480",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    fig3\n",
       "                </div>\n",
       "                <img src='' width=100.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4b0aa394e3f44e289b565d6aa8409086",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    fig4\n",
       "                </div>\n",
       "                <img src='' width=100.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b19a873f724c47fc92de1387335d96e8",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    fig5\n",
       "                </div>\n",
       "                <img src='' width=100.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "ret = search(start, dest, heuristic_none)\n",
    "for i, r in enumerate(ret):\n",
    "    ## 第二个参数为图像标题，请保证每一题标题不一致，否则冲突会有意想不到的结果\n",
    "    PlotEightDigit(r, f\"fig{i}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[((2, 8, 3), (1, 6, 4), (7, 0, 5)),\n",
       " ((2, 8, 3), (1, 0, 4), (7, 6, 5)),\n",
       " ((2, 0, 3), (1, 8, 4), (7, 6, 5)),\n",
       " ((0, 2, 3), (1, 8, 4), (7, 6, 5)),\n",
       " ((1, 2, 3), (0, 8, 4), (7, 6, 5)),\n",
       " ((1, 2, 3), (8, 0, 4), (7, 6, 5))]"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 答案\n",
    "search(start, dest, heuristic_diff)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3 八数码问题（二）\n",
    "请用启发式搜索算法求解以下八数码问题。\n",
    "\n",
    "请尝试采用以下两种启发函数：\n",
    "1. h(n)=“不在位”的将牌数\n",
    "2. h(n)=将牌“不在位”的距离和\n",
    "\n",
    "参考答案：\n",
    "\n",
    "```\n",
    "[((6, 0, 3), (1, 4, 7), (8, 5, 2)),\n",
    " ((0, 6, 3), (1, 4, 7), (8, 5, 2)),\n",
    " ((1, 6, 3), (0, 4, 7), (8, 5, 2)),\n",
    " ((1, 6, 3), (4, 0, 7), (8, 5, 2)),\n",
    " ((1, 6, 3), (4, 7, 0), (8, 5, 2)),\n",
    " ((1, 6, 3), (4, 7, 2), (8, 5, 0)),\n",
    " ((1, 6, 3), (4, 7, 2), (8, 0, 5)),\n",
    " ((1, 6, 3), (4, 0, 2), (8, 7, 5)),\n",
    " ((1, 6, 3), (0, 4, 2), (8, 7, 5)),\n",
    " ((1, 6, 3), (8, 4, 2), (0, 7, 5)),\n",
    " ((1, 6, 3), (8, 4, 2), (7, 0, 5)),\n",
    " ((1, 6, 3), (8, 4, 2), (7, 5, 0)),\n",
    " ((1, 6, 3), (8, 4, 0), (7, 5, 2)),\n",
    " ((1, 6, 3), (8, 0, 4), (7, 5, 2)),\n",
    " ((1, 0, 3), (8, 6, 4), (7, 5, 2)),\n",
    " ((1, 3, 0), (8, 6, 4), (7, 5, 2)),\n",
    " ((1, 3, 4), (8, 6, 0), (7, 5, 2)),\n",
    " ((1, 3, 4), (8, 6, 2), (7, 5, 0)),\n",
    " ((1, 3, 4), (8, 6, 2), (7, 0, 5)),\n",
    " ((1, 3, 4), (8, 0, 2), (7, 6, 5)),\n",
    " ((1, 3, 4), (8, 2, 0), (7, 6, 5)),\n",
    " ((1, 3, 0), (8, 2, 4), (7, 6, 5)),\n",
    " ((1, 0, 3), (8, 2, 4), (7, 6, 5)),\n",
    " ((1, 2, 3), (8, 0, 4), (7, 6, 5))]\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c030bd7b5f1f47de9a7bef704fb66e0c",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    2.3\n",
       "                </div>\n",
       "                <img src='' width=200.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "data_begin = ((6, \"\", 3), (1, 4, 7), (8, 5, 2))\n",
    "data_end = ((1, 2, 3), (8, \"\", 4), (7, 6, 5))\n",
    "fig, ax = plt.subplots(1, 2, num=\"2.3\", figsize=(2, 2))\n",
    "table = ax[0].table(\n",
    "    cellText=data_begin, loc=\"center\", cellLoc=\"center\", colWidths=[0.3, 0.3, 0.3]\n",
    ")\n",
    "ax[0].axis(\"off\")\n",
    "ax[0].set_title(\"start\")\n",
    "table = ax[1].table(\n",
    "    cellText=data_end, loc=\"center\", cellLoc=\"center\", colWidths=[0.3, 0.3, 0.3]\n",
    ")\n",
    "ax[1].axis(\"off\")\n",
    "ax[1].set_title(\"dest\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 答案\n",
    "start = ((6, 0, 3), (1, 4, 7), (8, 5, 2))\n",
    "drst = ((1, 2, 3), (8, 0, 4), (7, 6, 5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[((6, 0, 3), (1, 4, 7), (8, 5, 2)),\n",
       " ((0, 6, 3), (1, 4, 7), (8, 5, 2)),\n",
       " ((1, 6, 3), (0, 4, 7), (8, 5, 2)),\n",
       " ((1, 6, 3), (4, 0, 7), (8, 5, 2)),\n",
       " ((1, 6, 3), (4, 7, 0), (8, 5, 2)),\n",
       " ((1, 6, 3), (4, 7, 2), (8, 5, 0)),\n",
       " ((1, 6, 3), (4, 7, 2), (8, 0, 5)),\n",
       " ((1, 6, 3), (4, 0, 2), (8, 7, 5)),\n",
       " ((1, 6, 3), (0, 4, 2), (8, 7, 5)),\n",
       " ((1, 6, 3), (8, 4, 2), (0, 7, 5)),\n",
       " ((1, 6, 3), (8, 4, 2), (7, 0, 5)),\n",
       " ((1, 6, 3), (8, 4, 2), (7, 5, 0)),\n",
       " ((1, 6, 3), (8, 4, 0), (7, 5, 2)),\n",
       " ((1, 6, 3), (8, 0, 4), (7, 5, 2)),\n",
       " ((1, 0, 3), (8, 6, 4), (7, 5, 2)),\n",
       " ((1, 3, 0), (8, 6, 4), (7, 5, 2)),\n",
       " ((1, 3, 4), (8, 6, 0), (7, 5, 2)),\n",
       " ((1, 3, 4), (8, 6, 2), (7, 5, 0)),\n",
       " ((1, 3, 4), (8, 6, 2), (7, 0, 5)),\n",
       " ((1, 3, 4), (8, 0, 2), (7, 6, 5)),\n",
       " ((1, 3, 4), (8, 2, 0), (7, 6, 5)),\n",
       " ((1, 3, 0), (8, 2, 4), (7, 6, 5)),\n",
       " ((1, 0, 3), (8, 2, 4), (7, 6, 5)),\n",
       " ((1, 2, 3), (8, 0, 4), (7, 6, 5))]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 答案\n",
    "search(start, dest, heuristic_diff)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[((6, 0, 3), (1, 4, 7), (8, 5, 2)),\n",
       " ((0, 6, 3), (1, 4, 7), (8, 5, 2)),\n",
       " ((1, 6, 3), (0, 4, 7), (8, 5, 2)),\n",
       " ((1, 6, 3), (4, 0, 7), (8, 5, 2)),\n",
       " ((1, 6, 3), (4, 7, 0), (8, 5, 2)),\n",
       " ((1, 6, 3), (4, 7, 2), (8, 5, 0)),\n",
       " ((1, 6, 3), (4, 7, 2), (8, 0, 5)),\n",
       " ((1, 6, 3), (4, 0, 2), (8, 7, 5)),\n",
       " ((1, 6, 3), (0, 4, 2), (8, 7, 5)),\n",
       " ((1, 6, 3), (8, 4, 2), (0, 7, 5)),\n",
       " ((1, 6, 3), (8, 4, 2), (7, 0, 5)),\n",
       " ((1, 6, 3), (8, 4, 2), (7, 5, 0)),\n",
       " ((1, 6, 3), (8, 4, 0), (7, 5, 2)),\n",
       " ((1, 6, 3), (8, 0, 4), (7, 5, 2)),\n",
       " ((1, 0, 3), (8, 6, 4), (7, 5, 2)),\n",
       " ((1, 3, 0), (8, 6, 4), (7, 5, 2)),\n",
       " ((1, 3, 4), (8, 6, 0), (7, 5, 2)),\n",
       " ((1, 3, 4), (8, 6, 2), (7, 5, 0)),\n",
       " ((1, 3, 4), (8, 6, 2), (7, 0, 5)),\n",
       " ((1, 3, 4), (8, 0, 2), (7, 6, 5)),\n",
       " ((1, 3, 4), (8, 2, 0), (7, 6, 5)),\n",
       " ((1, 3, 0), (8, 2, 4), (7, 6, 5)),\n",
       " ((1, 0, 3), (8, 2, 4), (7, 6, 5)),\n",
       " ((1, 2, 3), (8, 0, 4), (7, 6, 5))]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 答案\n",
    "search(start, dest, heuristic_dist)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.4 栅格地图路径规划\n",
    "请通过编程实现针对栅格地图的广度优先搜索算法、深度优先搜索算法、Dijkstra算法以及A\\*算法。\n",
    "\n",
    "* 算法输入输出要求：\n",
    "  * 输入：图\n",
    "  * 输出：路径\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**栅格地图的表示**\n",
    "\n",
    "要求会用，不强制要求理解。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "class RasterMap:\n",
    "    def __init__(self, map_size: Tuple[int, int]):\n",
    "        assert map_size[0] > 0 and map_size[1] > 0\n",
    "        self.__map_size = map_size\n",
    "        self.__obstacle: Dict[Tuple[int, int], bool] = {}\n",
    "        self.__start: Tuple[int, int] = (0, 0)\n",
    "        self.__dest: Tuple[int, int] = (map_size[0] - 1, map_size[1] - 1)\n",
    "\n",
    "    @property\n",
    "    def size(self):\n",
    "        return self.__map_size\n",
    "\n",
    "    @size.setter\n",
    "    def size(self, size: Tuple[int, int]):\n",
    "        assert size[0] > 0 and size[1] > 0\n",
    "        self.__map_size = size\n",
    "\n",
    "    @property\n",
    "    def start(self):\n",
    "        return self.__start\n",
    "\n",
    "    @start.setter\n",
    "    def start(self, start: Tuple[int, int]):\n",
    "        assert self.in_bounds(start)\n",
    "        self.__start = start\n",
    "\n",
    "    @property\n",
    "    def dest(self):\n",
    "        return self.__dest\n",
    "\n",
    "    @dest.setter\n",
    "    def dest(self, dest: Tuple[int, int]):\n",
    "        assert self.in_bounds(dest)\n",
    "        self.__dest = dest\n",
    "\n",
    "    @property\n",
    "    def obstacle(self):\n",
    "        return self.__obstacle\n",
    "\n",
    "    def in_bounds(self, id: Tuple[int, int]) -> bool:\n",
    "        return 0 <= id[0] < self.size[0] and 0 <= id[1] < self.size[1]\n",
    "\n",
    "    def is_obstacle(self, id: Tuple[int, int]) -> bool:\n",
    "        return id in self.obstacle\n",
    "\n",
    "    def set_obstacle(self, id: Tuple[int, int], is_obstacle: bool):\n",
    "        assert self.in_bounds(id)\n",
    "        if is_obstacle:\n",
    "            self.obstacle[id] = True\n",
    "        else:\n",
    "            del self.obstacle[id]\n",
    "\n",
    "    def get_neighbors(self, id: Tuple[int, int]) -> List[Tuple[int, int]]:\n",
    "        (x, y) = id\n",
    "        neighbors = [(x + 1, y), (x - 1, y), (x, y - 1), (x, y + 1)]  # E W N S\n",
    "        if (x + y) % 2 == 0:\n",
    "            neighbors.reverse()  # S N W E\n",
    "        results = filter(self.in_bounds, neighbors)\n",
    "        results = filter(lambda x: not self.is_obstacle(x), results)\n",
    "        return list(results)\n",
    "\n",
    "    def save(self, path):\n",
    "        with open(path, \"wb\") as f:\n",
    "            pickle.dump(self, f)\n",
    "\n",
    "    def load(self, path):\n",
    "        with open(path, \"rb\") as f:\n",
    "            data = pickle.load(f)\n",
    "            self.size = data.size\n",
    "            self.__obstacle = data.obstacle\n",
    "            self.start = data.start\n",
    "            self.dest = data.dest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(4, 4), (2, 4), (3, 3), (3, 5)]\n",
      "(0, 1)\n",
      "(5, 6)\n"
     ]
    }
   ],
   "source": [
    "# 构建长宽分别为40、20的栅格地图\n",
    "map_example = RasterMap((40, 20))\n",
    "# 获取坐标为(3,4)的邻居\n",
    "print(map_example.get_neighbors((3, 4)))\n",
    "# 设置与获取起点\n",
    "map_example.start = (0, 1)\n",
    "print(map_example.start)\n",
    "# 设置与获取终点\n",
    "map_example.dest = (5, 6)\n",
    "print(map_example.dest)\n",
    "# 保存与载入地图\n",
    "# map_example.save(\"xxx.data\")\n",
    "# map_example.load(\"xxx.data\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**栅格地图可视化**\n",
    "\n",
    "不用看系列。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class PlotMap:\n",
    "    def __init__(self, raster_map: RasterMap, planner=None):\n",
    "        self.raster_map = raster_map\n",
    "        self.planner = planner\n",
    "        self.closed_list: List[Tuple[int, int]] = []\n",
    "        self.open_list: List[Tuple[int, int]] = []\n",
    "        self.path: List[Tuple[int, int]] = []\n",
    "        self.set_mode = \"O\"\n",
    "        self.processing_time = 0\n",
    "\n",
    "        self.fig, self.ax = plt.subplots(\n",
    "            num=f\"Map {self.planner.__name__}\" if self.planner else \"Map\"\n",
    "        )\n",
    "        self.btn = mpl.widgets.Button(plt.axes([0.1, 0.1, 0.05, 0.05]), \"O\")\n",
    "        self.cid = self.fig.canvas.mpl_connect(\"button_press_event\", self._click_cb)\n",
    "        self.btn.on_clicked(self._btn_cb)\n",
    "        self.text = self.ax.text(0, -0.75, \"\", fontsize=8, ha=\"left\", va=\"bottom\")\n",
    "\n",
    "        self._update_path()\n",
    "        self.show()\n",
    "\n",
    "    def _btn_cb(self, event):\n",
    "        if self.set_mode == \"O\":\n",
    "            self.set_mode = \"S\"\n",
    "            self.btn.label.set_text(\"S\")\n",
    "        elif self.set_mode == \"S\":\n",
    "            self.set_mode = \"D\"\n",
    "            self.btn.label.set_text(\"D\")\n",
    "        elif self.set_mode == \"D\":\n",
    "            self.set_mode = \"O\"\n",
    "            self.btn.label.set_text(\"O\")\n",
    "\n",
    "    def _update_data(self):\n",
    "        self.plot_data = np.ones(self.raster_map.size) * 8\n",
    "        for x, y in self.closed_list:\n",
    "            self.plot_data[x, y] = 10\n",
    "        for x, y in self.open_list:\n",
    "            self.plot_data[x, y] = 0\n",
    "        for x, y in self.path:\n",
    "            self.plot_data[x, y] = 4\n",
    "        self.plot_data[self.raster_map.start[0], self.raster_map.start[1]] = 7\n",
    "        self.plot_data[self.raster_map.dest[0], self.raster_map.dest[1]] = 9\n",
    "        for x, y in self.raster_map.obstacle:\n",
    "            self.plot_data[x, y] = 5\n",
    "\n",
    "    def _update_path(self):\n",
    "        self.processing_time = 0\n",
    "        if self.planner is not None:\n",
    "            self.closed_list = []\n",
    "            self.open_list = []\n",
    "            self.path = []\n",
    "            begin_time = time.time()\n",
    "            ret = self.planner(self.raster_map)\n",
    "            self.processing_time = time.time() - begin_time\n",
    "            if isinstance(ret, list):\n",
    "                self.path = ret\n",
    "                self._update_data()\n",
    "                self._show()\n",
    "            elif isinstance(ret, tuple) and len(ret) == 3:\n",
    "                self.path, self.closed_list, self.open_list = ret\n",
    "                self._update_data()\n",
    "                self._show()\n",
    "            else:\n",
    "                raise NotImplementedError()\n",
    "\n",
    "        else:\n",
    "            self._update_data()\n",
    "            self._show()\n",
    "\n",
    "    def _click_cb(self, event):\n",
    "        if event.inaxes is self.ax.axes:\n",
    "            col = int(event.xdata + 0.5)\n",
    "            row = int(event.ydata + 0.5)\n",
    "            if self.raster_map.in_bounds((col, row)):\n",
    "                if self.set_mode == \"O\":\n",
    "                    obs = self.raster_map.is_obstacle((col, row))\n",
    "                    self.raster_map.set_obstacle((col, row), not obs)\n",
    "                elif self.set_mode == \"S\":\n",
    "                    self.raster_map.start = (col, row)\n",
    "                elif self.set_mode == \"D\":\n",
    "                    self.raster_map.dest = (col, row)\n",
    "\n",
    "                self._update_path()\n",
    "\n",
    "    def _show(self):\n",
    "        self.ax.set_xticks(np.arange(-0.5, self.raster_map.size[0] + 0.5, 1))\n",
    "        self.ax.set_yticks(np.arange(-0.5, self.raster_map.size[1] + 0.5, 1))\n",
    "        self.ax.axes.xaxis.set_ticklabels([])\n",
    "        self.ax.axes.yaxis.set_ticklabels([])\n",
    "        self.ax.grid(True, color=\"white\", linewidth=1.5)\n",
    "        if len(self.path):\n",
    "            self.text.set_text(f\"path legth: {len(self.path)}\")\n",
    "        self.ax.imshow(self.plot_data.T, cmap=\"Set3\", vmin=0, vmax=11)\n",
    "\n",
    "    def show(self):\n",
    "        plt.show()\n",
    "\n",
    "    def show_animation(self):\n",
    "        self.ani_fig, self.ani_ax = plt.subplots(\n",
    "            num=f\"Animation {self.planner.__name__}\" if self.planner else \"Animation\"\n",
    "        )\n",
    "        self.ani_ax.cla()\n",
    "\n",
    "        matrix = np.ones(self.raster_map.size) * 8\n",
    "\n",
    "        def update(frame):\n",
    "            idx = frame % (len(self.closed_list) + 1)\n",
    "            if idx == len(self.closed_list):\n",
    "                for x, y in self.closed_list:\n",
    "                    matrix[x, y] = 10\n",
    "                for x, y in self.path:\n",
    "                    matrix[x, y] = 4\n",
    "                matrix[self.raster_map.start[0], self.raster_map.start[1]] = 7\n",
    "                matrix[self.raster_map.dest[0], self.raster_map.dest[1]] = 9\n",
    "                for x, y in self.raster_map.obstacle:\n",
    "                    matrix[x, y] = 5\n",
    "            else:\n",
    "                for x, y in self.closed_list[:idx]:\n",
    "                    matrix[x, y] = 10\n",
    "                expl_x, expl_y = self.closed_list[idx]\n",
    "                matrix[expl_x, expl_y] = 0\n",
    "                matrix[self.raster_map.start[0], self.raster_map.start[1]] = 7\n",
    "                matrix[self.raster_map.dest[0], self.raster_map.dest[1]] = 9\n",
    "                for x, y in self.raster_map.obstacle:\n",
    "                    matrix[x, y] = 5\n",
    "\n",
    "            self.ani_ax.cla()\n",
    "            self.ani_ax.set_xticks(np.arange(-0.5, self.raster_map.size[0] + 0.5, 1))\n",
    "            self.ani_ax.set_yticks(np.arange(-0.5, self.raster_map.size[1] + 0.5, 1))\n",
    "            self.ani_ax.xaxis.set_ticklabels([])\n",
    "            self.ani_ax.yaxis.set_ticklabels([])\n",
    "            self.ani_ax.grid(True, color=\"white\", linewidth=1.5)\n",
    "            self.ani_ax.imshow(matrix.T, cmap=\"Set3\", vmin=0, vmax=11)\n",
    "\n",
    "        self.ani = animation.FuncAnimation(\n",
    "            self.ani_fig,\n",
    "            update,\n",
    "            frames=len(self.closed_list) + 1,\n",
    "            interval=1,\n",
    "            repeat=False,\n",
    "        )\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算L2距离\n",
    "def l2_distance(x, y):\n",
    "    squared_diff = [(a - b) ** 2 for a, b in zip(x, y)]\n",
    "    return math.sqrt(sum(squared_diff))\n",
    "\n",
    "\n",
    "# 计算L1距离\n",
    "def l1_distance(x, y):\n",
    "    abs_diff = [abs(a - b) for a, b in zip(x, y)]\n",
    "    return sum(abs_diff)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**请在此实现广度优先搜索算法、深度优先搜索算法、Dijkstra算法以及A\\*算法（如时间不足优先完成A\\*算法）**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def bfs(graph: RasterMap):\n",
    "    return []\n",
    "\n",
    "\n",
    "def dfs(graph: RasterMap):\n",
    "    return []\n",
    "\n",
    "\n",
    "def dijkstra(graph: RasterMap):\n",
    "    return []\n",
    "\n",
    "\n",
    "def a_star(graph: RasterMap):\n",
    "    return []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 答案\n",
    "def bfs(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    queue = [start]\n",
    "    reached: Dict[Tuple[int, int], bool] = {start: True}\n",
    "    came_from: Dict[Tuple[int, int], Tuple[int, int]] = {}\n",
    "    path = []\n",
    "\n",
    "    while len(queue):\n",
    "        current = queue.pop(0)\n",
    "        if current == dest:\n",
    "            break\n",
    "        for next in graph.get_neighbors(current):\n",
    "            if next not in reached:\n",
    "                queue.append(next)\n",
    "                reached[next] = True\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not reached.get(dest):\n",
    "        return []\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1]\n",
    "\n",
    "\n",
    "def dfs(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    reached: Dict[str, bool] = {start: True}\n",
    "\n",
    "    def _dfs(graph, start: str, dest: str):\n",
    "        neighbors = [n for n in graph.get_neighbors(start) if n not in reached]\n",
    "        if dest in neighbors:\n",
    "            return [dest, start]\n",
    "        else:\n",
    "            for current in neighbors:\n",
    "                reached[current] = True\n",
    "                path = _dfs(graph, current, dest)\n",
    "                if len(path):\n",
    "                    path.append(start)\n",
    "                    return path\n",
    "            return []\n",
    "\n",
    "    path = _dfs(graph, start, dest)\n",
    "    return path[::-1]\n",
    "\n",
    "\n",
    "def dijkstra(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    queue = PriorityQueue()\n",
    "    cost_so_far: Dict[str, float] = {}\n",
    "    came_from: Dict[str, str] = {}\n",
    "    path = []\n",
    "    queue.put(start, 0)\n",
    "    cost_so_far[start] = 0\n",
    "\n",
    "    while not queue.empty():\n",
    "        current = queue.get()\n",
    "        if current == dest:\n",
    "            break\n",
    "        for next in graph.get_neighbors(current):\n",
    "            new_cost = cost_so_far[current] + l1_distance(current, next)\n",
    "            if next not in cost_so_far or new_cost < cost_so_far[next]:\n",
    "                priority = new_cost\n",
    "                queue.put(next, priority)\n",
    "                cost_so_far[next] = new_cost\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not cost_so_far.get(dest):\n",
    "        return []\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1]\n",
    "\n",
    "\n",
    "def a_star(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    queue = PriorityQueue()\n",
    "    cost_so_far: Dict[str, float] = {}\n",
    "    came_from: Dict[str, str] = {}\n",
    "    path = []\n",
    "    queue.put(start, 0)\n",
    "    cost_so_far[start] = 0\n",
    "\n",
    "    def heuristic(location):\n",
    "        return l1_distance(location, dest)\n",
    "\n",
    "    while not queue.empty():\n",
    "        current = queue.get()\n",
    "        if current == dest:\n",
    "            break\n",
    "        for next in graph.get_neighbors(current):\n",
    "            new_cost = cost_so_far[current] + l1_distance(current, next)\n",
    "            if next not in cost_so_far or new_cost < cost_so_far[next]:\n",
    "                priority = new_cost + heuristic(next)\n",
    "                queue.put(next, priority)\n",
    "                cost_so_far[next] = new_cost\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not cost_so_far.get(dest):\n",
    "        return []\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "map = RasterMap((20, 20))\n",
    "map.load(\"map1.data\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "ed19146645c444239d46b35e0663bd03",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAiN0lEQVR4nO3db4hl910/8M/Zu7OntnfvaVozLWtOXMyQwlaT3XbJg5Y02nZlowjqAysKKv6hhT6IIgt9kKqL4C0sVDeCUFD7yICIf0BsV1IKTWJ9EDvEX2VFvDHalCSm2N17Ntqcmc6c34PSy+xmN7k598zcM/N9vWDAm5vznvc93gzvOefuNmuapgkAAJJxaNkFAADYWwYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAeunq1avxqU996rp/9sM//MPxN3/zN6977H/+53/GW9/61oU7/M7v/E688sors8e/9Eu/FH/wB3/whnP+8R//MU6ePBknT56Md7/73fHRj3406rp+3ecAYLcYgPTSzQbgXjt//vx1A7Cte++9N5566ql4+umn46tf/Wq89NJL8Ud/9Eev+xwA7BYDkF2XZVk8/PDDcerUqbj77rvjz/7sz2bP/fzP/3ycPn067rnnnvjxH//xePHFFyMi4mMf+1hcu3YtTp48GadPn579+08++WTcf//9cdddd8XHPvaxub7/U089FR/84Afj9OnTcerUqfiLv/iL2XOf+cxn4u677473vOc98bu/+7uRZdns+0dE3H///XHy5Ml46aWXIiLiX//1X+NDH/pQ3H333fHTP/3TsbGx8brf/81vfnOsrKxERMTGxkZ861vfmn2f13oOAHZNA7ssIpqHH364aZqmeeaZZ5rbbrutefbZZ5umaZqXXnpp9u+Nx+Pmox/9aNM0TfPss882RVFcl/PAAw80P/mTP9lsbm42//d//9ccP368+fKXv/yq77fz2CtXrjQnT55snn/++aZpmuYb3/hGU5Zl8/Wvf7356le/2rzzne9sXnjhhaZpmua3fuu3mp3/SUREc+XKldnjX/zFX2zuu+++5n//93+bb3/728373ve+5tFHH22apmmeeuqp5sEHH7zlOXj22Webe+65p3nLW97S/MzP/ExT1/VczwHAbnAFkD3xq7/6qxER8QM/8APxgQ98IB5//PGIiHj00Ufj9OnT8YM/+IPxx3/8x/H000+/Zs5HPvKROHz4cHzP93xPnDx5Mp555pnX/Pe//OUvx3/8x3/Egw8+GCdPnowPf/jDERHxb//2b/HFL34xzp49G+985zsjIuLXfu3XXvd1/NRP/VS8+c1vjsFgEPfdd9/s+58+fTo+97nP3fK448ePxz//8z/Hiy++GHVdx1/91V/N9RwA7AYDkKXIsiyefPLJeOSRR+Jzn/tc/Mu//Et8+tOfft3P3L3pTW+a/d+DwSC+/e1vv+a/3zRNvPvd746nn3569vW1r30tPvjBD9600+t5o9//RsPhMH72Z3/2utvg8zwHAF0yANkTn/3sZyPiO39C94knnoj7778/rly5EkePHo23v/3tsbGxEZ/5zGdm//5oNIpvfetbc33G7rW8733vi2effTa+8IUvzP7Z008/HRsbG/EjP/Ij8fd///ezz/f9yZ/8yXXHHj16NKbT6ULfPyJiMpnE5uZmRHznc35//dd/Hffcc8/rPgcAu8UAZE9sbW3FqVOn4kd/9EfjkUceiePHj8fZs2fjXe96V7zrXe+a/WGL73rb294Wv/ALvxD33HPPdX8I5I267bbb4u/+7u/i937v9+Lee++NEydOxCc+8YnY3t6OH/qhH4qHH3443v/+98d73vOeeOWVV6Ioitmxv/mbvxlnzpy57g+B3Mo//dM/xY/92I/d9LkvfvGLcerUqbj33nvj1KlT8Y53vCM++clPvu5zALBbsqZpmmWX4GDLsiyuXLnSyd/N17Vr167F0aNHIyLi4sWLcenSpfj85z+/5FYAsLsOL7sALNMnPvGJ+Id/+IfY3NyMY8eOXXcbGgAOKlcAAQAS4zOAAACJMQABABJjAAIAJMYfAmEudV1HXdezx9vb2/HNb34z3v72t/vfrgXYh5qmiWvXrsWxY8fi0CHXg1JjADKX8Xgc58+fX3YNADr23HPPxR133LHsGuwxfwqYudx4BXA6ncadd94Zjz/+eAyHw4Wy77rrroiI1/3f9d2rHJ106mOOTjp13en222+Psizj6tWr1/0l+KTBFUDmkud55Hn+qn8+HA7jLW95S+vcLMtiNBrNstr+PtJVjk469TFHJ512s5OP8aTJTX8AgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIzOFlF2D/y7Ksk2P7kKOTTn3M0Umn3exEmrKmaZpll6D/6rqOuq5nj6uqirIsYzqdxmg0WmIzANqoqiqKovBzPFFuATOX8XgcRVHMvsqyXHYlAKAlVwCZy62uAK6vr8dwOGydm2VZrK2tRUTEZDKJtm/HrnJ00qmPOTrptBudVldXXQFMmM8AMpc8zyPP85s+19XvEE3TdJLVVU6XWTrtbU6XWX3L6TJLp73N6TKry06kyS1gAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQmMPLLsD+l2VZJ8f2IUcnnfqYo5NOu9mJNGVN0zTLLkH/1XUddV3PHldVFWVZxnQ6jdFotMRmALRRVVUUReHneKLcAmYu4/E4iqKYfZVluexKAEBLrgAyl1tdAVxfX4/hcNg6N8uyWFtbi4iIyWQSbd+OXeWk1Gn7sYcitjZad4rBkTh05mKnnfp4nvqQo5NOu9FpdXXVFcCE+Qwgc8nzPPI8v+lzXf0O0TRNJ1ld5XSZ1cdOsbWx2ADc4SCfp77ldJml097mdJnVZSfS5BYwAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJObwsguw/2VZ1smxfchJqVMMjixS6brjD/J56kOOTjrtZifSlDVN0yy7BP1X13XUdT17XFVVlGUZ0+k0RqPREpsB0EZVVVEUhZ/jiXILmLmMx+MoimL2VZblsisBAC25AshcbnUFcH19PYbDYevcLMtibW0tIiImk0m0fTt2lZNSp+3HHorY2mjdKQZH4tCZi5126uN56kOOTjrtRqfV1VVXABPmM4DMJc/zyPP8ps919TtE0zSdZHWV02VWHzvF1sZiA3CHg3ye+pbTZZZOe5vTZVaXnUiTW8AAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxh5ddgP0vy7JOju1DTkqdYnBkkUrXHX+Qz1MfcnTSaTc7kaasaZpm2SXov7quo67r2eOqqqIsy5hOpzEajZbYDIA2qqqKoij8HE+UW8DMZTweR1EUs6+yLJddCQBoyRVA5nKrK4Dr6+sxHA5b52ZZFmtraxERMZlMou3bcWfOhUuXY3Or/dt6ZZDFubMnIiJi6/+9GLHdMutQFoN73hkRi722iN05T9uPPRSxtdG6UwyOxKEzFzvt1Mfz1IccnXTajU6rq6uuACbMZwCZS57nkef5TZ/r6neIpmk6ydrcahYagNfZbtoPwB26em2dZm1tLDYAd+iqUx/PU99yuszSaW9zuszqshNpcgsYACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEnN42QXY/7Is6+TYrnJWBu1zXnX8oQWyDnXz2m48vqvzFIMji1S67vg+vAe6zOpbjk467WYn0pQ1TdMsuwT9V9d11HU9e1xVVZRlGdPpNEaj0RKbAdBGVVVRFIWf44lyC5i5jMfjKIpi9lWW5bIrAQAtuQLIXG51BXB9fT2Gw2Hr3CzLYm1tLSIiLly6HJtb7d6OK4Mszp09sXDOjVmTySTa/iey87UtktNl1s6c7cceitjaaN0pBkfi0JmLnXbq43nqQ45OOu1Gp9XVVVcAE+YzgMwlz/PI8/ymz3X1O8TmVrPQcOs6J+I7r62L19dVTqdZWxuLDcAdDvJ56ltOl1k67W1Ol1lddiJNbgEDACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYg4vuwD7X5ZlnRy7Mmifs/PYRXJuPL6r17ZITpdZ1x07OLJIpeuOP8jnqQ85Oum0m51IU9Y0TbPsEvRfXddR1/XscVVVUZZlTKfTGI1GS2wGQBtVVUVRFH6OJ8otYOYyHo+jKIrZV1mWy64EALTkCiBzudUVwPX19RgOh61zsyyLtbW1iIi4cOlybG61ezuuDLI4d/ZERERMJpNY5G29s9MiWV3l7Fan7cceitjaaN0pBkfi0JmLnXbq43nqQ45OOu1Gp9XVVVcAE+YzgMwlz/PI8/ymz3X1O8TmVtN6AO7UNE1nnbrK6mOn2NpYbADucJDPU99yuszSaW9zuszqshNpcgsYACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAk5vCyC7D/ZVnWybErg/Y5O49dpM+Nx3f12vrYKQZHFql03fEH+Tz1IUcnnXazE2nKmqZpll2C/qvrOuq6nj2uqirKsozpdBqj0WiJzQBoo6qqKIrCz/FEuQXMXMbjcRRFMfsqy3LZlQCAllwBZC63ugK4vr4ew+GwdW6WZbG2thYRERcuXY7NrXZvx5VBFufOnoiIiO3HHorY2mjdKQZH4tCZi4tndZWzDzpNJpNo+6Nk53tgkZwus/qWo5NOu9FpdXXVFcCE+Qwgc8nzPPI8v+lzXf0OsbnVtB6A19naWGzY7EbWAe/UNE0n74OucrrM6ltOl1k67W1Ol1lddiJNbgEDACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYg4vuwD7X5ZlnRy7Mmifc92xgyOtc151/CJZXeV0mbVLnbp6DyyS02VW33J00mk3O5GmrGmaZtkl6L+6rqOu69njqqqiLMuYTqcxGo2W2AyANqqqiqIo/BxPlFvAzGU8HkdRFLOvsiyXXQkAaMkVQOZyqyuA6+vrMRwOW+dmWRZra2sREXHh0uXY3Gr3dlwZZHHu7ImFc27Mmkwm0fY/kZ2vbZGcLrN02p85Oum0G51WV1ddAUyYzwAylzzPI8/zmz7X1e8Qm1vNQsOt65yI77y2Ll5fVzldZum0P3O6zNJpb3O6zOqyE2lyCxgAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTm8LILsP9lWdbJsSuD9jk7j10k58bju3pti+R0maXT/szRSafd7ESasqZpmmWXoP/quo66rmePq6qKsixjOp3GaDRaYjMA2qiqKoqi8HM8UW4BM5fxeBxFUcy+yrJcdiUAoCVXAJnLra4Arq+vx3A4bJ2bZVmsra1FRMRkMom2b8edORcuXY7NrfZv65VBFufOnlg4a2fOIq8tYnfOk077J0cnnXaj0+rqqiuACfMZQOaS53nkeX7T57r6HaJpmk6yNreahQbgbmR19dq6zNJpf+Z0maXT3uZ0mdVlJ9LkFjAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAk5vCyC7D/ZVnWybFd5awM2ufcePwiWTuPXeS13Xh8H863Tnubo5NOu9mJNGVN0zTLLkH/1XUddV3PHldVFWVZxnQ6jdFotMRmALRRVVUUReHneKLcAmYu4/E4iqKYfZVluexKAEBLrgAyl1tdAVxfX4/hcNg6N8uyWFtbi4iIyWQSbd+OXeXcmHXh0uXY3GqXtTLI4tzZEwvn3JjVx/Ok0+7m6KTTbnRaXV11BTBhPgPIXPI8jzzPb/pcV79DNE3TSVZXORERm1vNQsOt65yIfp4nnfYup8ssnfY2p8usLjuRJreAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYg4vuwD7X5ZlnRzbh5wbj18ZtM/aeewiOTce38fzpNPu5uik0252Ik1Z0zTNskvQf3VdR13Xs8dVVUVZljGdTmM0Gi2xGQBtVFUVRVH4OZ4ot4CZy3g8jqIoZl9lWS67EgDQkiuAzOVWVwDX19djOBy2zs2yLNbW1iIiYjKZRNu3Y1c5u9XpwqXLsbnVvtPKIItzZ08snLUzp4/n6aB1OsivTaf932l1ddUVwIT5DCBzyfM88jy/6XNd/Q7RNE0nWV3ldJm1udUsNAB3I6uP5+kgdzrIr63LLJ32Nod0uQUMAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTm87ALsf1mWdXJsH3J2q9PKYLFOO49fJGvnsX08Twet00F+bTodnE6kKWuapll2Cfqvruuo63r2uKqqKMsyptNpjEajJTYDoI2qqqIoCj/HE+UWMHMZj8dRFMXsqyzLZVcCAFpyBZC53OoK4Pr6egyHw9a5WZbF2tpaRERMJpNo+3bsKmc/dLpw6XJsbrXLWhlkce7siYVzbszq43nqQ6fdem3bjz0UsbXRLmhwJA6dubh4TpdZPe900N6X381aXV11BTBhPgPIXPI8jzzPb/pcV79DNE3TSVZXOV1mddlpc6tZaLh1nRPRz/PUt05dvrbY2lhsJHWd02VWDzsd5Pcl6XILGAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJObwsguw/2VZ1smxfcjZD51WBu2zdh67SM6Nx/fxPPWh0269thgcaR+089hFcrrM6nmng/a+7OJ49r+saZpm2SXov7quo67r2eOqqqIsy5hOpzEajZbYDIA2qqqKoij8HE+UW8DMZTweR1EUs6+yLJddCQBoyRVA5nKrK4Dr6+sxHA5b52ZZFmtraxERMZlMou3bsauclDpduHQ5Nrfad1oZZHHu7ImFs3bm9PE89SHnxqztxx6K2NpoFzQ4EofOXOy8Ux/Pk06vnbW6uuoKYMJ8BpC55HkeeZ7f9LmufodomqaTrK5yuszqY6fNrWahAbgbWX08T33LiYjvjL+2A3CHg3y+u8w66J1Ik1vAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkJjDyy7A/pdlWSfH9iEnpU4rg8U67Tx+kaydx/bxPPUh51XHD460D9px7EE73zq1yyJNWdM0zbJL0H91XUdd17PHVVVFWZYxnU5jNBotsRkAbVRVFUVR+DmeKLeAmct4PI6iKGZfZVkuuxIA0JIrgMzlVlcA19fXYzgcts7NsizW1tYiImIymUTbt2NXOTq1y7pw6XJsbrXLWhlkce7siYVzbszqw3narfO9/dhDEVsb7YIGR+LQmYudd+rjedLptbNWV1ddAUyYzwAylzzPI8/zmz7X1e8QTdN0ktVVTpdZB73T5laz0HDrOieif+epy/MdWxvtB+AOB/19qRPcmlvAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMYeXXYD9L8uyTo7tQ45O7bJWBu2zdh67SM6Nx/fhPO3W+Y7BkfZBO4496O9LnebLIk1Z0zTNskvQf3VdR13Xs8dVVUVZljGdTmM0Gi2xGQBtVFUVRVH4OZ4ot4CZy3g8jqIoZl9lWS67EgDQkiuAzOVWVwDX19djOBy2zs2yLNbW1iIiYjKZRNu3Y1c5Oi2304VLl2Nzq32nlUEW586eWDhrZ04fz/f2Yw9FbG20CxociUNnLnbeqY/nSafXzlpdXXUFMGE+A8hc8jyPPM9v+lxXv0M0TdNJVlc5XWbpNJ/NrWahAbgbWX0837G10X4A7tDH94BOe5tDutwCBgBIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQcXnYB9r8syzo5tg85Oi2308pgsU47j18ka+exfTzfMTjSPmjHsX18D+i0951IU9Y0TbPsEvRfXddR1/XscVVVUZZlTKfTGI1GS2wGQBtVVUVRFH6OJ8otYOYyHo+jKIrZV1mWy64EALTkCiBzudUVwPX19RgOh61zsyyLtbW1iIiYTCbR9u3YVY5OB6fThUuXY3OrXdbKIItzZ090mtPla9t+7KGIrY12QYMjcejMxc479fE9oNNrZ62urroCmDCfAWQueZ5Hnuc3fa6r3yGapukkq6ucLrN02tuciIjNrab1cNuNnC5fW2xttB+AOxz094BOcGtuAQMAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQcXnYB9r8syzo5tg85Oh2cTiuD9lk7j+0qp8vXFoMj7YN2HHvQ3wM6zZdFmrKmaZpll6D/6rqOuq5nj6uqirIsYzqdxmg0WmIzANqoqiqKovBzPFFuATOX8XgcRVHMvsqyXHYlAKAlVwCZy62uAK6vr8dwOGydm2VZrK2tRUTEZDKJtm/HrnJ00unGnAuXLsfmVruclUEW586eWDjnxqztxx6K2NpoFzQ4EofOXIyIbs93H8/Tly48Htub261yDq0cigfOfSAi+vm+7KLT6uqqK4AJ8xlA5pLneeR5ftPnuvodommaTrK6yukyS6e9zekya3OrWWiQdJ0TEd8Zf20H4A5dnu8+nqftze3WA3CnPr4vu+xEmtwCBgBIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQcXnYB9r8syzo5tg85Oul047Erg/Y5O49dJOdVxw+OtA/acWyX57uP5+nQSvtrHDuP7eP7sstOpClrmqZZdgn6r67rqOt69riqqijLMqbTaYxGoyU2A6CNqqqiKAo/xxPlFjBzGY/HURTF7Kssy2VXAgBacgWQudzqCuD6+noMh8PWuVmWxdraWkRETCaTaPt27CpHJ512K+fCpcuxudX+ta0Msjh39sTCWV3l7Fang/Ye6HOn1dVVVwAT5jOAzCXP88jz/KbPdfU7RNM0nWR1ldNllk57m9NlVlc5m1vNQmNrN7L62Okgvwe6zOqyE2lyCxgAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTm8LILLNP29nY8//zzcfTo0ciybM+/f9M0ce3atTh27FgcOrR/t/gi527nsX3I0Umn3cpZGSz22nYev0hWVzm71emgvQf2QyfSlDVN0yy7xLJ8/etfj7Isl10jnnvuubjjjjuWXeM11XUddV3PHldVFWVZxnQ6jdFotMRmALRRVVUUReHneKKSvgJ49OjRiIj40pe+FMPhcM+//8svvxwPPPDArEefjcfjOH/+/LJrAAAdSPoK4Hd/+/nKV76ytAH43ve+d1/89nWrK4Dr6+sLnbssy2JtbS0iIiaTSbR9O3aVo5NOfczRSafd6LS6uuoKYMKSvgLI/PI8jzzPb/pcV79DNE3TSVZXOV1m6bS3OV1m9S2nyyyd9jany6wuO5Gm/fsnDwAAaMUABABIjFvALbzwwgvxyCOPxBNPPBFXr16N22+/PT70oQ/Fxz/+8bjtttuWXQ8A4DUZgG/Qc889Fx/5yEfi+PHj8elPfzruuOOO+Pd///e4cOFCPPHEE/Hnf/7n8da3vnXZNQEAbskt4Dfo/PnzsbKyEn/6p38a9913Xxw7diweeOCB+OxnPxv//d//Hb//+7+/7IoAAK/JAHwDrl69Gk8++WT83M/9XLzpTW+67rnbb789fuInfiI+//nP+5NZAECvGYBvwH/9139F0zRx11133fT5u+66K6bTaXzzm9/c42YAAPMzAFtwhQ8A2M8MwDfgzjvvjCzL4plnnrnp888880wURRFve9vb9rgZAMD8DMA34Lbbbov3v//98eijj8Yrr7xy3XPf+MY34m//9m/jwQcfjCzLltQQAOD1GYBv0Cc/+cnY2NiIX/mVX4mnnnoqXnjhhXj88cfjl3/5l+Md73hH/MZv/MayKwIAvCZ/D+AbdPz48fjLv/zL+MM//MP49V//9ZhOp/G93/u98eEPfzg+/vGP+zsAAYDeMwBb+L7v+7741Kc+tewaAACtGIAsbJHPPO48tg85OunUxxyddNrNTqQpaxL+O02qqoqiKOIrX/lKDIfDPf/+L7/8crz3ve+N6XQao9Foz7//G1HXddR1PXs8nU7jzjvvjOeee6733QF4taqqoizLuHr1ahRFsew67DFXAJnLeDyO8+fPv+qfl2W5hDYAdOV//ud/DMAEuQLoCuBcbrwCePXq1fj+7//++NrXvrbwD47v/ha66NXErnJ00qmPOTrp1HWn797JuXLlij/AmCBXAJlLnueR5/mr/nlRFJ2N19Fo1ElWVzldZum0tzldZvUtp8ssnfY2p8usLjsdOuRvhEuR/68DACQm6SuA3737/fLLLy/l+3/3+yZ8Fx4AWIKkB+C1a9ciIuKBBx5Yeo/99gHcPM/jt3/7t296W3hZWTrp1MdOB/m16aQT+1fSfwhke3s7nn/++Th69OhS/k6kpmni2rVrcezYMZ/BAAD2TNIDEAAgRS47AQAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYv4/cmSLyFcOQIsAAAAASUVORK5CYII=",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map bfs\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, bfs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "62c87bc987c14946900eeffc68ec5e34",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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jRoVjz76aFx//fUD64sWLYqDBw/G3/7t3x5zzuzZs+M3f/M347777htY+8u//Mu46aab4s0334zi4mPbeKgrgNXV1dHd3R0VFRVn9kEBAGdFT09PVFZWJv38XRBXAEtLS2P69OnR1tY2sNbf3x9tbW1RV1c35DlvvfXWMZFXUlISERHHa+KysrKoqKgYdAMAON8UxHsAIyIaGxtj0aJFMWPGjJg5c2asWbMmDh8+HIsXL46IiIULF8bkyZOjubk5IiLmzp0bq1evjquvvjpqa2vjhRdeiLvuuivmzp07EIIAAIWoYAJw3rx5sX///lixYkV0dnbGtGnTorW1deAHQ/bu3Tvoit+dd94ZRUVFceedd8YvfvGLuOiii2Lu3Lnx9a9/PV8PAQAgJwriPYD54j0EAHD+8fxdIO8BBADg5AlAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQUVAC2tLRETU1NlJeXR21tbWzbtu2Exx88eDCWLFkSEydOjLKysrjssstiy5YtOZoWACA/RuR7gDNl48aN0djYGGvXro3a2tpYs2ZNNDQ0xO7du2P8+PHHHN/b2xsf//jHY/z48fHoo4/G5MmT45VXXokxY8bkfngAgBwqyrIsy/cQZ0JtbW189KMfjQceeCAiIvr7+6O6ujq+8IUvxLJly445fu3atXHffffFrl27YuTIkad0nz09PVFZWRnd3d1RUVFxWvMDALnh+btAXgLu7e2N7du3R319/cBacXFx1NfXR3t7+5Dn/OhHP4q6urpYsmRJVFVVxZVXXhkrV66Mvr6+497PkSNHoqenZ9ANAOB8UxABeODAgejr64uqqqpB61VVVdHZ2TnkOXv27IlHH300+vr6YsuWLXHXXXfFN77xjfja17523Ptpbm6OysrKgVt1dfUZfRwAALlQEAF4Kvr7+2P8+PHx7W9/O6ZPnx7z5s2LO+64I9auXXvcc5YvXx7d3d0Dt3379uVwYgCAM6Mgfghk3LhxUVJSEl1dXYPWu7q6YsKECUOeM3HixBg5cmSUlJQMrH3wgx+Mzs7O6O3tjdLS0mPOKSsri7KysjM7PABAjhXEFcDS0tKYPn16tLW1Daz19/dHW1tb1NXVDXnOrFmz4oUXXoj+/v6Bteeffz4mTpw4ZPwBABSKggjAiIjGxsZYt25dfO9734udO3fGLbfcEocPH47FixdHRMTChQtj+fLlA8ffcsst8cYbb8Rtt90Wzz//fGzevDlWrlwZS5YsyddDAADIiYJ4CTgiYt68ebF///5YsWJFdHZ2xrRp06K1tXXgB0P27t0bxcX/17vV1dXx+OOPx9KlS+Oqq66KyZMnx2233Ra33357vh4CAEBOFMznAOaDzxECgPOP5+8CegkYAICTIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAElNQAdjS0hI1NTVRXl4etbW1sW3btpM6b8OGDVFUVBTXX3/92R0QAOAcUDABuHHjxmhsbIympqbYsWNHTJ06NRoaGuL1118/4Xkvv/xy/PEf/3HMnj07R5MCAORXwQTg6tWr48Ybb4zFixfHFVdcEWvXro1Ro0bF+vXrj3tOX19ffPazn4277747Lr300hxOCwCQPwURgL29vbF9+/aor68fWCsuLo76+vpob28/7nlf/epXY/z48XHDDTec1P0cOXIkenp6Bt0AAM43BRGABw4ciL6+vqiqqhq0XlVVFZ2dnUOe89RTT8VDDz0U69atO+n7aW5ujsrKyoFbdXX1ac0NAJAPBRGAw3Xo0KFYsGBBrFu3LsaNG3fS5y1fvjy6u7sHbvv27TuLUwIAnB0j8j3AmTBu3LgoKSmJrq6uQetdXV0xYcKEY45/8cUX4+WXX465c+cOrPX390dExIgRI2L37t0xZcqUY84rKyuLsrKyMzw9AEBuFcQVwNLS0pg+fXq0tbUNrPX390dbW1vU1dUdc/zll18ezz77bHR0dAzcPvWpT8W1114bHR0dXtoFAApaQVwBjIhobGyMRYsWxYwZM2LmzJmxZs2aOHz4cCxevDgiIhYuXBiTJ0+O5ubmKC8vjyuvvHLQ+WPGjImIOGYdAKDQFEwAzps3L/bv3x8rVqyIzs7OmDZtWrS2tg78YMjevXujuLggLngCAJyWoizLsnwPcb7q6emJysrK6O7ujoqKinyPAwCcBM/fBfIeQAAATp4ABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEhMQQVgS0tL1NTURHl5edTW1sa2bduOe+y6deti9uzZMXbs2Bg7dmzU19ef8HgAgEJRMAG4cePGaGxsjKamptixY0dMnTo1Ghoa4vXXXx/y+K1bt8ZnPvOZ+OlPfxrt7e1RXV0dn/jEJ+IXv/hFjicHAMitoizLsnwPcSbU1tbGRz/60XjggQciIqK/vz+qq6vjC1/4Qixbtuw9z+/r64uxY8fGAw88EAsXLjyp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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map dfs\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, dfs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "b268e803de7f4caab68365a423a1cf66",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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jRoVjz76aFx//fUD64sWLYqDBw/G3/7t3x5zzuzZs+M3f/M347777htY+8u//Mu46aab4s0334zi4mPbeKgrgNXV1dHd3R0VFRVn9kEBAGdFT09PVFZWJv38XRBXAEtLS2P69OnR1tY2sNbf3x9tbW1RV1c35DlvvfXWMZFXUlISERHHa+KysrKoqKgYdAMAON8UxHsAIyIaGxtj0aJFMWPGjJg5c2asWbMmDh8+HIsXL46IiIULF8bkyZOjubk5IiLmzp0bq1evjquvvjpqa2vjhRdeiLvuuivmzp07EIIAAIWoYAJw3rx5sX///lixYkV0dnbGtGnTorW1deAHQ/bu3Tvoit+dd94ZRUVFceedd8YvfvGLuOiii2Lu3Lnx9a9/PV8PAQAgJwriPYD54j0EAHD+8fxdIO8BBADg5AlAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQUVAC2tLRETU1NlJeXR21tbWzbtu2Exx88eDCWLFkSEydOjLKysrjssstiy5YtOZoWACA/RuR7gDNl48aN0djYGGvXro3a2tpYs2ZNNDQ0xO7du2P8+PHHHN/b2xsf//jHY/z48fHoo4/G5MmT45VXXokxY8bkfngAgBwqyrIsy/cQZ0JtbW189KMfjQceeCAiIvr7+6O6ujq+8IUvxLJly445fu3atXHffffFrl27YuTIkad0nz09PVFZWRnd3d1RUVFxWvMDALnh+btAXgLu7e2N7du3R319/cBacXFx1NfXR3t7+5Dn/OhHP4q6urpYsmRJVFVVxZVXXhkrV66Mvr6+497PkSNHoqenZ9ANAOB8UxABeODAgejr64uqqqpB61VVVdHZ2TnkOXv27IlHH300+vr6YsuWLXHXXXfFN77xjfja17523Ptpbm6OysrKgVt1dfUZfRwAALlQEAF4Kvr7+2P8+PHx7W9/O6ZPnx7z5s2LO+64I9auXXvcc5YvXx7d3d0Dt3379uVwYgCAM6Mgfghk3LhxUVJSEl1dXYPWu7q6YsKECUOeM3HixBg5cmSUlJQMrH3wgx+Mzs7O6O3tjdLS0mPOKSsri7KysjM7PABAjhXEFcDS0tKYPn16tLW1Daz19/dHW1tb1NXVDXnOrFmz4oUXXoj+/v6Bteeffz4mTpw4ZPwBABSKggjAiIjGxsZYt25dfO9734udO3fGLbfcEocPH47FixdHRMTChQtj+fLlA8ffcsst8cYbb8Rtt90Wzz//fGzevDlWrlwZS5YsyddDAADIiYJ4CTgiYt68ebF///5YsWJFdHZ2xrRp06K1tXXgB0P27t0bxcX/17vV1dXx+OOPx9KlS+Oqq66KyZMnx2233Ra33357vh4CAEBOFMznAOaDzxECgPOP5+8CegkYAICTIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAElNQAdjS0hI1NTVRXl4etbW1sW3btpM6b8OGDVFUVBTXX3/92R0QAOAcUDABuHHjxmhsbIympqbYsWNHTJ06NRoaGuL1118/4Xkvv/xy/PEf/3HMnj07R5MCAORXwQTg6tWr48Ybb4zFixfHFVdcEWvXro1Ro0bF+vXrj3tOX19ffPazn4277747Lr300hxOCwCQPwURgL29vbF9+/aor68fWCsuLo76+vpob28/7nlf/epXY/z48XHDDTec1P0cOXIkenp6Bt0AAM43BRGABw4ciL6+vqiqqhq0XlVVFZ2dnUOe89RTT8VDDz0U69atO+n7aW5ujsrKyoFbdXX1ac0NAJAPBRGAw3Xo0KFYsGBBrFu3LsaNG3fS5y1fvjy6u7sHbvv27TuLUwIAnB0j8j3AmTBu3LgoKSmJrq6uQetdXV0xYcKEY45/8cUX4+WXX465c+cOrPX390dExIgRI2L37t0xZcqUY84rKyuLsrKyMzw9AEBuFcQVwNLS0pg+fXq0tbUNrPX390dbW1vU1dUdc/zll18ezz77bHR0dAzcPvWpT8W1114bHR0dXtoFAApaQVwBjIhobGyMRYsWxYwZM2LmzJmxZs2aOHz4cCxevDgiIhYuXBiTJ0+O5ubmKC8vjyuvvHLQ+WPGjImIOGYdAKDQFEwAzps3L/bv3x8rVqyIzs7OmDZtWrS2tg78YMjevXujuLggLngCAJyWoizLsnwPcb7q6emJysrK6O7ujoqKinyPAwCcBM/fBfIeQAAATp4ABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEhMQQVgS0tL1NTURHl5edTW1sa2bduOe+y6deti9uzZMXbs2Bg7dmzU19ef8HgAgEJRMAG4cePGaGxsjKamptixY0dMnTo1Ghoa4vXXXx/y+K1bt8ZnPvOZ+OlPfxrt7e1RXV0dn/jEJ+IXv/hFjicHAMitoizLsnwPcSbU1tbGRz/60XjggQciIqK/vz+qq6vjC1/4Qixbtuw9z+/r64uxY8fGAw88EAsXLjyp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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map dijkstra\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, dijkstra)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "87a68101cec14332aa6f46b04308edf5",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAiHklEQVR4nO3db4hl910/8M/Zu7OntnfvaVozDWtOXMwlha0mu+2SBy1ptO3KRhHUB1YUVPxDC30QRRb6IFUXwVtYqG4EoaD2kQER/4DYrqQUmsT6IHaIv0pEvDHalCSm2N17Ntqcmc6c34OSYXazm9yce2bumfm+XjDgzc15z/ue3A7vOefumjVN0wQAAMk4tOwCAADsLQMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgvXTlypX49Kc/fc0/++Ef/uH4m7/5mzc89j//8z/j7W9/+8Idfud3fideeeWV7ce/9Eu/FH/wB3/wpnP+8R//MU6ePBknT56M97znPfGxj30s6rp+w+cAYLcYgPTSjQbgXjt//vw1A7Cte+65J5588sl46qmn4mtf+1q89NJL8Ud/9Edv+BwA7BYDkF2XZVk89NBDcerUqbjrrrviz/7sz7af+/mf//k4ffp03H333fHjP/7j8eKLL0ZExMc//vG4evVqnDx5Mk6fPr397z/xxBNx3333xZ133hkf//jH5/r+Tz75ZHzoQx+K06dPx6lTp+Iv/uIvtp/77Gc/G3fddVe8973vjd/93d+NLMu2v39ExH333RcnT56Ml156KSIi/vVf/zU+/OEPx1133RU//dM/Hevr62/4/d/61rfGyspKRESsr6/Ht7/97e3v83rPAcCuaWCXRUTz0EMPNU3TNM8880xzyy23NM8++2zTNE3z0ksvbf97k8mk+djHPtY0TdM8++yzTVEU1+Tcf//9zU/+5E82Gxsbzf/93/81x48fb77yla+85vvtPPby5cvNyZMnm+eff75pmqb55je/2ZRl2XzjG99ovva1rzW33XZb88ILLzRN0zS/9Vu/1ez8n0RENJcvX95+/Iu/+IvNvffe2/zv//5v853vfKd5//vf3zzyyCNN0zTNk08+2TzwwAM3PQfPPvtsc/fddzdve9vbmp/5mZ9p6rqe6zkA2A2uALInfvVXfzUiIn7gB34gPvjBD8Zjjz0WERGPPPJInD59On7wB38w/viP/zieeuqp18356Ec/GocPH47v+Z7viZMnT8Yzzzzzuv/+V77ylfiP//iPeOCBB+LkyZPxkY98JCIi/u3f/i2+9KUvxdmzZ+O2226LiIhf+7Vfe8PX8VM/9VPx1re+NQaDQdx7773b3//06dPx+c9//qbHHT9+PP75n/85XnzxxajrOv7qr/5qrucAYDcYgCxFlmXxxBNPxMMPPxyf//zn41/+5V/iM5/5zBt+5u4tb3nL9v89GAziO9/5zuv++03TxHve85546qmntr++/vWvx4c+9KEbdnojb/b7X284HMbP/uzPXnMbfJ7nAKBLBiB74nOf+1xEfPdP6D7++ONx3333xeXLl+Po0aPxzne+M9bX1+Ozn/3s9r8/Go3i29/+9lyfsXs973//++PZZ5+NL37xi9v/7Kmnnor19fX4kR/5kfj7v//77c/3/cmf/Mk1xx49ejRms9lC3z8iYjqdxsbGRkR893N+f/3Xfx133333Gz4HALvFAGRPbG5uxqlTp+JHf/RH4+GHH47jx4/H2bNn493vfne8+93v3v7DFq96xzveEb/wC78Qd9999zV/COTNuuWWW+Lv/u7v4vd+7/finnvuiRMnTsQnP/nJ2Nraih/6oR+Khx56KD7wgQ/Ee9/73njllVeiKIrtY3/zN38zzpw5c80fArmZf/qnf4of+7Efu+FzX/rSl+LUqVNxzz33xKlTp+Jd73pXfOpTn3rD5wBgt2RN0zTLLsHBlmVZXL58uZO/m69rV69ejaNHj0ZExMWLF+PSpUvxhS98YcmtAGB3HV52AVimT37yk/EP//APsbGxEceOHbvmNjQAHFSuAAIAJMZnAAEAEmMAAgAkxgAEAEiMPwTCXOq6jrqutx9vbW3Ft771rXjnO9/p/3ctwD7UNE1cvXo1jh07FocOuR6UGgOQuUwmkzh//vyyawDQ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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map a_star\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, a_star)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3 算法比较\n",
    "请将上述四种搜索算法的**已搜索区域**、**待搜索区域**可视化，更进一步可将上述搜索算法的搜索过程动态展示。举例说明这四种算法的特点，各自在什么场景中适用，并完成四种算法在不同场景中的性能比较。\n",
    "\n",
    "提示：在栅格地图场景中，bfs和Dijsktra算法性能有什么差异？为什么？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 答案\n",
    "def bfs_pro(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    queue = [start]\n",
    "    reached: Dict[Tuple[int, int], bool] = {start: True}\n",
    "    came_from: Dict[Tuple[int, int], Tuple[int, int]] = {}\n",
    "    closed_list: List[Tuple[int, int]] = []\n",
    "    path = []\n",
    "\n",
    "    while len(queue):\n",
    "        current = queue.pop(0)\n",
    "        if current == dest:\n",
    "            break\n",
    "        closed_list.append(current)\n",
    "        for next in graph.get_neighbors(current):\n",
    "            if next not in reached:\n",
    "                queue.append(next)\n",
    "                reached[next] = True\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not reached.get(dest):\n",
    "        return [], closed_list, queue[:]\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1], closed_list, queue[:]\n",
    "\n",
    "\n",
    "def dfs_pro(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    reached: Dict[str, bool] = {start: True}\n",
    "    closed_list: List[Tuple[int, int]] = []\n",
    "    open_list: List[Tuple[int, int]] = []\n",
    "\n",
    "    def _dfs(graph, start, dest):\n",
    "        neighbors = [n for n in graph.get_neighbors(start) if n not in reached]\n",
    "        if dest in neighbors:\n",
    "            return [dest, start]\n",
    "        else:\n",
    "            closed_list.append(start)\n",
    "            open_list.extend(neighbors)\n",
    "            for current in neighbors:\n",
    "                reached[current] = True\n",
    "                path = _dfs(graph, current, dest)\n",
    "                if len(path):\n",
    "                    path.append(start)\n",
    "                    return path\n",
    "            return []\n",
    "\n",
    "    path = _dfs(graph, start, dest)\n",
    "    return path[::-1], closed_list, open_list\n",
    "\n",
    "\n",
    "def dijkstra_pro(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    queue = PriorityQueue()\n",
    "    cost_so_far: Dict[str, float] = {}\n",
    "    came_from: Dict[str, str] = {}\n",
    "    path = []\n",
    "    queue.put(start, 0)\n",
    "    cost_so_far[start] = 0\n",
    "\n",
    "    while not queue.empty():\n",
    "        current = queue.get()\n",
    "        if current == dest:\n",
    "            break\n",
    "        for next in graph.get_neighbors(current):\n",
    "            new_cost = cost_so_far[current] + l1_distance(current, next)\n",
    "            if next not in cost_so_far or new_cost < cost_so_far[next]:\n",
    "                priority = new_cost\n",
    "                queue.put(next, priority)\n",
    "                cost_so_far[next] = new_cost\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not cost_so_far.get(dest):\n",
    "        return [], list(cost_so_far.keys()), list(queue.data)\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1], list(cost_so_far.keys()), list(queue.data)\n",
    "\n",
    "\n",
    "def a_star_pro(graph):\n",
    "    start = graph.start\n",
    "    dest = graph.dest\n",
    "    queue = PriorityQueue()\n",
    "    cost_so_far: Dict[str, float] = {}\n",
    "    came_from: Dict[str, str] = {}\n",
    "    path = []\n",
    "    queue.put(start, 0)\n",
    "    cost_so_far[start] = 0\n",
    "\n",
    "    def heuristic(location):\n",
    "        return l1_distance(location, dest)\n",
    "\n",
    "    while not queue.empty():\n",
    "        current = queue.get()\n",
    "        if current == dest:\n",
    "            break\n",
    "        for next in graph.get_neighbors(current):\n",
    "            new_cost = cost_so_far[current] + l1_distance(current, next)\n",
    "            if next not in cost_so_far or new_cost < cost_so_far[next]:\n",
    "                priority = new_cost + heuristic(next)\n",
    "                queue.put(next, priority)\n",
    "                cost_so_far[next] = new_cost\n",
    "                came_from[next] = current\n",
    "\n",
    "    if not cost_so_far.get(dest):\n",
    "        return [], list(cost_so_far.keys()), list(queue.data)\n",
    "\n",
    "    path = [dest]\n",
    "    current = came_from.get(dest)\n",
    "    while current is not None:\n",
    "        path.append(current)\n",
    "        current = came_from.get(current)\n",
    "    return path[::-1], list(cost_so_far.keys()), list(queue.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "01aff9ff603e435ba679b55c9b25c523",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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AAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDELM+7wDxNJpP4xje+ESsrK5Fl2Y5//bqu4+TJk3H11VdHr3fxbvE2t930sV3lLGftbsvp43stniNNH9sm58zj23x/08e2vc9vx5/dpdbpUv7edLp0OpGmrK7ret4l5uU//uM/oizLedeIZ599Nq655pp51zivqqqiqqrN98fjcZRlGaPRKPr9/hybAdDEeDyOoig8jicq6TOAKysrERHxhS98Ifbs2bPjX//FF1+MW2+9dbPHIhsOh3H48OF51wAAOpD0GcBXnv185StfmdsAfNvb3nZRPPs61xnAY8eOtbrtsiyL1dXViIhYW1uLpnfHrnLOzLr3+NHYqCeNcpazXhzad6B1zplZi3g76bS9OTrptB2dBoOBM4AJS/oMILPL8zzyPH/Vz3X1HKKu606yusqJiNioJ62GW9c5EYt5O+m0czldZum0szldZnXZiTRdvL95AABAIwYgAEBiXAJu4Jvf/Gbcc8898cgjj8SJEyfiqquuine+853x3ve+N6644op51wMAOC8D8AI9++yz8e53vzuuu+66+NM//dO45ppr4t/+7d/iwx/+cDzyyCPxN3/zN/H6179+3jUBAM7JJeALdPjw4bjsssviL//yL+PgwYNx9dVXx6233hof//jH47nnnos/+7M/m3dFAIDzMgAvwIkTJ+LIkSPxC7/wC/G6171uy+euuuqq+Mmf/Mn47Gc/6zezAICFZgBegH//93+Puq7j+uuvf9XPX3/99TEajeLb3/72DjcDAJidAdiAM3wAwMXMALwA1157bWRZFk8++eSrfv7JJ5+Moijiyiuv3OFmAACzMwAvwBVXXBE333xz3H///XHq1Kktn/vv//7v+MxnPhPvete7IsuyOTUEAHhtBuAF+uAHPxjr6+vxq7/6q/HlL385vvnNb8bDDz8cv/IrvxLf9V3fFb/9278974oAAOfl7wG8QNddd1186lOfij//8z+P3/qt34rRaBR79+6NH/3RH433vve9/g5AAGDhGYANfPd3f3d86EMfmncNAIBGDEBaa/Oax+ljFyHnzOOXs+avkpg+tk3Omccv4u2k0/bm6KTTdnYiTVmd8N9pMh6PoyiK+MpXvhJ79uzZ8a//4osvxtve9rYYjUbR7/d3/OtfiKqqoqqqzfdHo1Fce+218eyzzy58dwDONh6PoyzLOHHiRBRFMe867DBnAJnJcDiMw4cPn/Xxsizn0AaArvzP//yPAZggZwCdAZzJmWcAT5w4EW9605vimWeeaf3A8cqz0LZnE7vK0UmnRczRSaeuO71yJeeFF17wC4wJcgaQmeR5Hnmen/Xxoig6G6/9fr+TrK5yuszSaWdzusxatJwus3Ta2Zwus7rs1Ov5G+FS5E8dACAxSZ8BfOXq94svvjiXr//K1034KjwAMAdJD8CTJ09GRMStt9469x4X2wtw8zyP3//933/Vy8LzytJJp0XsdCl/bzrpxMUr6V8CmUwm8Y1vfCNWVlbm8nci1XUdJ0+ejKuvvtprMACAHZP0AAQASJHTTgAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkBgDEAAgMQYgAEBiDEAAgMQYgAAAiTEAAQASYwACACTGAAQASIwBCACQGAMQACAxBiAAQGIMQACAxBiAAACJMQABABJjAAIAJMYABABIjAEIAJAYAxAAIDEGIABAYgxAAIDEGIAAAIkxAAEAEmMAAgAkxgAEAEiMAQgAkJj/B6CPBnuSIOusAAAAAElFTkSuQmCC",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map bfs_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, bfs_pro)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8888453360024d48b582defd95fb1d2b",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAevklEQVR4nO3df2zfdZ3A8Vfb0W8h0jJvrvtxX9yBh6jAhhurBRfCpWcTyLz9cbEHZpsLgugk3JpTNn6sIrpOBLJEigsTDpOT25QAZ1xTDnsuBqlZ3NYEZYPgwO2MLdvp2jm0Ze3n/rjw9eo6XEf3/Y7v+/FIvn/0zeez7+vLm/J95vP9sYosy7IAACAZlaUeAACA4hKAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiSmbAPzxj38cixcvjlmzZkVFRUU89dRTf/Gcbdu2xYc//OHI5XLxvve9Lx599NFTPicAQKmVTQAeOXIk5s6dGx0dHSd0/CuvvBLXXHNNXHXVVdHb2xv//M//HJ/+9Kfj6aefPsWTAgCUVkWWZVmph5hsFRUV8eSTT8aSJUuOe8ytt94aW7dujZ///OeFtX/6p3+KQ4cORVdXVxGmBAAojbK5AjhRPT090dTUNGatubk5enp6SjQRAEBxTCn1AKXS19cX9fX1Y9bq6+tjcHAw/vCHP8SZZ555zDlDQ0MxNDRU+Hl0dDR++9vfxl/91V9FRUXFKZ8ZAHj7siyLw4cPx6xZs6KyMs1rYckG4Mlob2+Pu+66q9RjAACTYP/+/fHXf/3XpR6jJJINwBkzZkR/f/+Ytf7+/qitrR336l9ExJo1a6K1tbXw88DAQJx77rmxf//+qK2tPaXzAgCTY3BwMPL5fJx99tmlHqVkkg3AxsbG6OzsHLP2zDPPRGNj43HPyeVykcvljlmvra0VgADwDpPy27fK5oXv3//+99Hb2xu9vb0R8X9f89Lb2xv79u2LiP+7erds2bLC8TfddFPs3bs3vvjFL8aePXviwQcfjO9+97uxatWqUowPAFA0ZROAP/vZz+LSSy+NSy+9NCIiWltb49JLL421a9dGRMRvfvObQgxGRPzN3/xNbN26NZ555pmYO3du3HffffGtb30rmpubSzI/AECxlOX3ABbL4OBg1NXVxcDAgJeAAeAdwvN3GV0BBADgxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMSUVQB2dHTEnDlzoqamJhoaGmL79u1vefyGDRvi/e9/f5x55pmRz+dj1apV8cc//rFI0wIAlEbZBOCWLVuitbU12traYufOnTF37txobm6O1157bdzjH3vssVi9enW0tbXF7t274+GHH44tW7bEbbfdVuTJAQCKq2wC8P77748bbrghVqxYER/84Adj48aNcdZZZ8Ujjzwy7vHPPfdcXHHFFXHdddfFnDlz4mMf+1hce+21f/GqIQDAO11ZBODw8HDs2LEjmpqaCmuVlZXR1NQUPT09455z+eWXx44dOwrBt3fv3ujs7Iyrr766KDMDAJTKlFIPMBkOHjwYIyMjUV9fP2a9vr4+9uzZM+451113XRw8eDA++tGPRpZlcfTo0bjpppve8iXgoaGhGBoaKvw8ODg4OQ8AAKCIyuIK4MnYtm1brFu3Lh588MHYuXNnPPHEE7F169a4++67j3tOe3t71NXVFW75fL6IEwMATI6KLMuyUg/xdg0PD8dZZ50Vjz/+eCxZsqSwvnz58jh06FD8x3/8xzHnLFq0KD7ykY/E17/+9cLav/3bv8WNN94Yv//976Oy8tg2Hu8KYD6fj4GBgaitrZ3cBwUAnBKDg4NRV1eX9PN3WVwBrK6ujvnz50d3d3dhbXR0NLq7u6OxsXHcc15//fVjIq+qqioiIo7XxLlcLmpra8fcAADeacriPYAREa2trbF8+fJYsGBBLFy4MDZs2BBHjhyJFStWRETEsmXLYvbs2dHe3h4REYsXL477778/Lr300mhoaIiXX3457rzzzli8eHEhBAEAylHZBGBLS0scOHAg1q5dG319fTFv3rzo6uoqfDBk3759Y6743XHHHVFRURF33HFH/PrXv473vOc9sXjx4vjqV79aqocAAFAUZfEewFLxHgIAeOfx/F0m7wEEAODECUAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxJRVAHZ0dMScOXOipqYmGhoaYvv27W95/KFDh2LlypUxc+bMyOVyccEFF0RnZ2eRpgUAKI0ppR5gsmzZsiVaW1tj48aN0dDQEBs2bIjm5uZ48cUXY/r06cccPzw8HH//938f06dPj8cffzxmz54dv/rVr+Kcc84p/vAAAEVUkWVZVuohJkNDQ0Ncdtll8cADD0RExOjoaOTz+bj55ptj9erVxxy/cePG+PrXvx579uyJM84446Tuc3BwMOrq6mJgYCBqa2vf1vwAQHF4/i6Tl4CHh4djx44d0dTUVFirrKyMpqam6OnpGfec73//+9HY2BgrV66M+vr6uOiii2LdunUxMjJy3PsZGhqKwcHBMTcA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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Animation bfs_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot.show_animation()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "489664ab34d34e7688ba67eccb6c68a8",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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jRoVjz76aFx//fUD64sWLYqDBw/G3/7t3x5zzuzZs+M3f/M347777htY+8u//Mu46aab4s0334zi4mPbeKgrgNXV1dHd3R0VFRVn9kEBAGdFT09PVFZWJv38XRBXAEtLS2P69OnR1tY2sNbf3x9tbW1RV1c35DlvvfXWMZFXUlISERHHa+KysrKoqKgYdAMAON8UxHsAIyIaGxtj0aJFMWPGjJg5c2asWbMmDh8+HIsXL46IiIULF8bkyZOjubk5IiLmzp0bq1evjquvvjpqa2vjhRdeiLvuuivmzp07EIIAAIWoYAJw3rx5sX///lixYkV0dnbGtGnTorW1deAHQ/bu3Tvoit+dd94ZRUVFceedd8YvfvGLuOiii2Lu3Lnx9a9/PV8PAQAgJwriPYD54j0EAHD+8fxdIO8BBADg5AlAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQUVAC2tLRETU1NlJeXR21tbWzbtu2Exx88eDCWLFkSEydOjLKysrjssstiy5YtOZoWACA/RuR7gDNl48aN0djYGGvXro3a2tpYs2ZNNDQ0xO7du2P8+PHHHN/b2xsf//jHY/z48fHoo4/G5MmT45VXXokxY8bkfngAgBwqyrIsy/cQZ0JtbW189KMfjQceeCAiIvr7+6O6ujq+8IUvxLJly445fu3atXHffffFrl27YuTIkad0nz09PVFZWRnd3d1RUVFxWvMDALnh+btAXgLu7e2N7du3R319/cBacXFx1NfXR3t7+5Dn/OhHP4q6urpYsmRJVFVVxZVXXhkrV66Mvr6+497PkSNHoqenZ9ANAOB8UxABeODAgejr64uqqqpB61VVVdHZ2TnkOXv27IlHH300+vr6YsuWLXHXXXfFN77xjfja17523Ptpbm6OysrKgVt1dfUZfRwAALlQEAF4Kvr7+2P8+PHx7W9/O6ZPnx7z5s2LO+64I9auXXvcc5YvXx7d3d0Dt3379uVwYgCAM6Mgfghk3LhxUVJSEl1dXYPWu7q6YsKECUOeM3HixBg5cmSUlJQMrH3wgx+Mzs7O6O3tjdLS0mPOKSsri7KysjM7PABAjhXEFcDS0tKYPn16tLW1Daz19/dHW1tb1NXVDXnOrFmz4oUXXoj+/v6Bteeffz4mTpw4ZPwBABSKggjAiIjGxsZYt25dfO9734udO3fGLbfcEocPH47FixdHRMTChQtj+fLlA8ffcsst8cYbb8Rtt90Wzz//fGzevDlWrlwZS5YsyddDAADIiYJ4CTgiYt68ebF///5YsWJFdHZ2xrRp06K1tXXgB0P27t0bxcX/17vV1dXx+OOPx9KlS+Oqq66KyZMnx2233Ra33357vh4CAEBOFMznAOaDzxECgPOP5+8CegkYAICTIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAElNQAdjS0hI1NTVRXl4etbW1sW3btpM6b8OGDVFUVBTXX3/92R0QAOAcUDABuHHjxmhsbIympqbYsWNHTJ06NRoaGuL1118/4Xkvv/xy/PEf/3HMnj07R5MCAORXwQTg6tWr48Ybb4zFixfHFVdcEWvXro1Ro0bF+vXrj3tOX19ffPazn4277747Lr300hxOCwCQPwURgL29vbF9+/aor68fWCsuLo76+vpob28/7nlf/epXY/z48XHDDTec1P0cOXIkenp6Bt0AAM43BRGABw4ciL6+vqiqqhq0XlVVFZ2dnUOe89RTT8VDDz0U69atO+n7aW5ujsrKyoFbdXX1ac0NAJAPBRGAw3Xo0KFYsGBBrFu3LsaNG3fS5y1fvjy6u7sHbvv27TuLUwIAnB0j8j3AmTBu3LgoKSmJrq6uQetdXV0xYcKEY45/8cUX4+WXX465c+cOrPX390dExIgRI2L37t0xZcqUY84rKyuLsrKyMzw9AEBuFcQVwNLS0pg+fXq0tbUNrPX390dbW1vU1dUdc/zll18ezz77bHR0dAzcPvWpT8W1114bHR0dXtoFAApaQVwBjIhobGyMRYsWxYwZM2LmzJmxZs2aOHz4cCxevDgiIhYuXBiTJ0+O5ubmKC8vjyuvvHLQ+WPGjImIOGYdAKDQFEwAzps3L/bv3x8rVqyIzs7OmDZtWrS2tg78YMjevXujuLggLngCAJyWoizLsnwPcb7q6emJysrK6O7ujoqKinyPAwCcBM/fBfIeQAAATp4ABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEhMQQVgS0tL1NTURHl5edTW1sa2bduOe+y6deti9uzZMXbs2Bg7dmzU19ef8HgAgEJRMAG4cePGaGxsjKamptixY0dMnTo1Ghoa4vXXXx/y+K1bt8ZnPvOZ+OlPfxrt7e1RXV0dn/jEJ+IXv/hFjicHAMitoizLsnwPcSbU1tbGRz/60XjggQciIqK/vz+qq6vjC1/4Qixbtuw9z+/r64uxY8fGAw88EAsXLjyp++zp6YnKysro7u6OioqK05ofAMgNz98FcgWwt7c3tm/fHvX19QNrxcXFUV9fH+3t7Sf1Pd56661455134n3ve99xjzly5Ej09PQMugEAnG8KIgAPHDgQfX19UVVVNWi9qqoqOjs7T+p73H777TFp0qRBEfmrmpubo7KycuBWXV19WnMDAORDQQTg6Vq1alVs2LAhNm3aFOXl5cc9bvny5dHd3T1w27dvXw6nBAA4M0bke4AzYdy4cVFSUhJdXV2D1ru6umLChAknPPf++++PVatWxU9+8pO46qqrTnhsWVlZlJWVnfa8AAD5VBBXAEtLS2P69OnR1tY2sNbf3x9tbW1RV1d33PPuvffeuOeee6K1tTVmzJiRi1EBAPKuIK4ARkQ0NjbGokWLYsaMGTFz5sxYs2ZNHD58OBYvXhwREQsXLozJkydHc3NzRET86Z/+aaxYsSIeeeSRqKmpGXiv4IUXXhgXXnhh3h4HAMDZVjABOG/evNi/f3+sWLEiOjs7Y9q0adHa2jrwgyF79+6N4uL/u+D5rW99K3p7e+P3fu/3Bn2fpqam+MpXvpLL0QEAcqpgPgcwH3yOEACcfzx/F8h7AAEAOHkCEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMSPyPUA+9ff3x6uvvhqjR4+OoqKiYZ/f09Mz6L/DlWVZHDp0KCZNmhTFxVocAMiNpAPw1Vdfjerq6tP+Pqf7Pfbt2xcXX3zxac8BAHAykg7A0aNHR0TEP/3TP8WFF16Y8/t/8803Y86cOQNzAADkQtIB+O7LvhdeeGFeAvBX5wAAyAVvPAMASIwABABIjAAEAEhM0u8BPFWvvfZa/MVf/EX87Gc/i4MHD8ZFF10Uv/3bvx1LliyJsWPH5ns8AIATEoDDtG/fvpg3b17U1NTE6tWr4+KLL47/+I//iPvuuy9+9rOfxcaNG2PMmDH5HhMA4Li8BDxMd999d4wcOTLWr18fM2fOjEmTJsWcOXPiu9/9bnR1dcWf/dmf5XtEAIATEoDDcPDgwXjqqadi/vz5UV5ePuhrF110UcydOzf+4R/+IbIsy9OEAADvTQAOwyuvvBJZlsWUKVOG/PqUKVOiu7s73njjjRxPBgBw8gTgKXCFDwA4nwnAYbjkkkuiqKgoXnzxxSG//uKLL0ZlZWW8733vy/FkAAAnTwAOw9ixY2PWrFnxyCOPxNtvvz3oa/v374+/+7u/i9/5nd/xq90AgHOaABymu+66K3p7e+OGG26If/mXf4nXXnstnnzyyfjc5z4XVVVVsXTp0nyPCABwQgUVgC0tLVFTUxPl5eVRW1sb27ZtO+HxmzZtGvZ91NTUxN/8zd9EdXV1fPGLX4yPf/zjsWLFiqitrY0NGzb4DEAA4JxXMB8EvXHjxmhsbIy1a9dGbW1trFmzJhoaGmL37t0xfvz4Y45/+umn43Of+9wp3dfkyZNj1apVpzsyAEBeFMwVwNWrV8eNN94YixcvjiuuuCLWrl0bo0aNivXr1w95/J//+Z9HfX19jqcEAMi/grgC2NvbG9u3b4/ly5cPrBUXF0d9fX20t7cPeU57e3vceuut8eMf/zhXYx5XT09PvkcAgGS8+7yb8se6FUQAHjhwIPr6+qKqqmrQelVVVezatWvIczo7O+Oiiy7KxXjvqbq6Ot8jAEBy/uu//isqKyvzPUZeFEQAnu/27dsXFRUV+R7jvNbT0xPV1dX+Ls8B9uLcYj/OHfbi3NHd3R2XXHJJ0p/bWxABOG7cuCgpKYmurq5B611dXTFhwoQhz5kwYULs378/F+O9p4qKCv8zOEP8XZ477MW5xX6cO+zFuaO4uGB+FGLYCuKRl5aWxvTp06OtrW1grb+/P9ra2qKurm7Ic+rq6mLr1q05mhAA4NxREFcAIyIaGxtj0aJFMWPGjJg5c2asWbMmDh8+HIsXL46IiIULF8bkyZOjubk5IiJuu+22mD17dkREvPnmm3mZ+d37TflNqABA7hVMAM6bNy/2798fK1asiM7Ozpg2bVq0trYO/GDI3r17B13qveaaa6KlpSVuueWWmDNnTr7GjoiIQ4cOJfsm1DOlrKwsmpqaoqysLN+jJM9enFvsx7nDXpw77EVEUZbw5af+/v549dVXY/To0Xn5/b1ZlsWhQ4di0qRJSb8PAQDIraQDEAAgRS47AQAkRgACACRGAAIAJEYAvoeWlpaoqamJ8vLyqK2tjW3btp3w+L/+67+Oyy+/PMrLy+PDH/5wbNmyJUeTFr7h7MW6deti9uzZMXbs2Bg7dmzU19e/595x8ob77+JdGzZsiKKiorj++uvP7oAJGe5eHDx4MJYsWRITJ06MsrKyuOyyy/x/6gwa7n6sWbMmPvCBD8QFF1wQ1dXVsXTp0nj77bdzNG3hevLJJ2Pu3LkxadKkKCoqih/+8Ifvec7WrVvjIx/5SJSVlcX73//+ePjhh8/6nHmVcVwbNmzISktLs/Xr12f//u//nt14443ZmDFjsq6uriGP//nPf56VlJRk9957b/bcc89ld955ZzZy5Mjs2WefzfHkhWe4ezF//vyspaUle+aZZ7KdO3dmf/AHf5BVVlZm//mf/5njyQvPcPfiXS+99FI2efLkbPbs2dnv/u7v5mbYAjfcvThy5Eg2Y8aM7Lrrrsueeuqp7KWXXsq2bt2adXR05HjywjTc/fj+97+flZWVZd///vezl156KXv88ceziRMnZkuXLs3x5IVny5Yt2R133JE99thjWURkmzZtOuHxe/bsyUaNGpU1NjZmzz33XPbNb34zKykpyVpbW3MzcB4IwBOYOXNmtmTJkoE/9/X1ZZMmTcqam5uHPP7Tn/509slPfnLQWm1tbfaHf/iHZ3XOFAx3L37V0aNHs9GjR2ff+973ztaIyTiVvTh69Gh2zTXXZN/5zneyRYsWCcAzZLh78a1vfSu79NJLs97e3lyNmJTh7seSJUuy3/qt3xq01tjYmM2aNeuszpmakwnAL33pS9mHPvShQWvz5s3LGhoazuJk+eUl4OPo7e2N7du3R319/cBacXFx1NfXR3t7+5DntLe3Dzo+IqKhoeG4x3NyTmUvftVbb70V77zzTtK/+PtMONW9+OpXvxrjx4+PG264IRdjJuFU9uJHP/pR1NXVxZIlS6KqqiquvPLKWLlyZfT19eVq7IJ1KvtxzTXXxPbt2wdeJt6zZ09s2bIlrrvuupzMzP9J8fm7YH4TyJl24MCB6OvrG/hNIu+qqqqKXbt2DXlOZ2fnkMd3dnaetTlTcCp78atuv/32mDRp0jH/wBmeU9mLp556Kh566KHo6OjIwYTpOJW92LNnT/zjP/5jfPazn40tW7bECy+8ELfeemu888470dTUlIuxC9ap7Mf8+fPjwIED8bGPfSyyLIujR4/GzTffHF/+8pdzMTL/z/Gev3t6euKXv/xlXHDBBXma7OxxBZCCt2rVqtiwYUNs2rQpysvL8z1OUg4dOhQLFiyIdevWxbhx4/I9TvL6+/tj/Pjx8e1vfzumT58e8+bNizvuuCPWrl2b79GStHXr1li5cmU8+OCDsWPHjnjsscdi8+bNcc899+R7NBLgCuBxjBs3LkpKSqKrq2vQeldXV0yYMGHIcyZMmDCs4zk5p7IX77r//vtj1apV8ZOf/CSuuuqqszlmEoa7Fy+++GK8/PLLMXfu3IG1/v7+iIgYMWJE7N69O6ZMmXJ2hy5Qp/LvYuLEiTFy5MgoKSkZWPvgBz8YnZ2d0dvbG6WlpWd15kJ2Kvtx1113xYIFC+Lzn/98RER8+MMfjsOHD8dNN90Ud9xxh18RmkPHe/6uqKgoyKt/Ea4AHldpaWlMnz492traBtb6+/ujra0t6urqhjynrq5u0PEREU888cRxj+fknMpeRETce++9cc8990Rra2vMmDEjF6MWvOHuxeWXXx7PPvtsdHR0DNw+9alPxbXXXhsdHR1RXV2dy/ELyqn8u5g1a1a88MILAxEeEfH888/HxIkTxd9pOpX9eOutt46JvHfjPPNbWnMqyefvfP8Uyrlsw4YNWVlZWfbwww9nzz33XHbTTTdlY8aMyTo7O7Msy7IFCxZky5YtGzj+5z//eTZixIjs/vvvz3bu3Jk1NTX5GJgzZLh7sWrVqqy0tDR79NFHs9dee23gdujQoXw9hIIx3L34VX4K+MwZ7l7s3bs3Gz16dPZHf/RH2e7du7O///u/z8aPH5997Wtfy9dDKCjD3Y+mpqZs9OjR2V/91V9le/bsyX784x9nU6ZMyT796U/n6yEUjEOHDmXPPPNM9swzz2QRka1evTp75plnsldeeSXLsixbtmxZtmDBgoHj3/0YmD/5kz/Jdu7cmbW0tPgYmNR985vfzC655JKstLQ0mzlzZvbP//zPA1+bM2dOtmjRokHH/+AHP8guu+yyrLS0NPvQhz6Ubd68OccTF67h7MWv//qvZxFxzK2pqSn3gxeg4f67+P8E4Jk13L14+umns9ra2qysrCy79NJLs69//evZ0aNHczx14RrOfrzzzjvZV77ylWzKlClZeXl5Vl1dnd16663Zf//3f+d+8ALz05/+dMjngHf//hctWpTNmTPnmHOmTZuWlZaWZpdeemn23e9+N+dz51JRlrnODACQEu8BBABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIzP8Aaug2NonrhygAAAAASUVORK5CYII=",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map dfs_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, dfs_pro)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "955ad76eb4f641578325ee04ab419424",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAevklEQVR4nO3df2zfdZ3A8Vfb0W8h0jJvrvtxX9yBh6jAhhurBRfCpWcTyLz9cbEHZpsLgugk3JpTNn6sIrpOBLJEigsTDpOT25QAZ1xTDnsuBqlZ3NYEZYPgwO2MLdvp2jm0Ze3n/rjw9eo6XEf3/Y7v+/FIvn/0zeez7+vLm/J95vP9sYosy7IAACAZlaUeAACA4hKAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiSmbAPzxj38cixcvjlmzZkVFRUU89dRTf/Gcbdu2xYc//OHI5XLxvve9Lx599NFTPicAQKmVTQAeOXIk5s6dGx0dHSd0/CuvvBLXXHNNXHXVVdHb2xv//M//HJ/+9Kfj6aefPsWTAgCUVkWWZVmph5hsFRUV8eSTT8aSJUuOe8ytt94aW7dujZ///OeFtX/6p3+KQ4cORVdXVxGmBAAojbK5AjhRPT090dTUNGatubk5enp6SjQRAEBxTCn1AKXS19cX9fX1Y9bq6+tjcHAw/vCHP8SZZ555zDlDQ0MxNDRU+Hl0dDR++9vfxl/91V9FRUXFKZ8ZAHj7siyLw4cPx6xZs6KyMs1rYckG4Mlob2+Pu+66q9RjAACTYP/+/fHXf/3XpR6jJJINwBkzZkR/f/+Ytf7+/qitrR336l9ExJo1a6K1tbXw88DAQJx77rmxf//+qK2tPaXzAgCTY3BwMPL5fJx99tmlHqVkkg3AxsbG6OzsHLP2zDPPRGNj43HPyeVykcvljlmvra0VgADwDpPy27fK5oXv3//+99Hb2xu9vb0R8X9f89Lb2xv79u2LiP+7erds2bLC8TfddFPs3bs3vvjFL8aePXviwQcfjO9+97uxatWqUowPAFA0ZROAP/vZz+LSSy+NSy+9NCIiWltb49JLL421a9dGRMRvfvObQgxGRPzN3/xNbN26NZ555pmYO3du3HffffGtb30rmpubSzI/AECxlOX3ABbL4OBg1NXVxcDAgJeAAeAdwvN3GV0BBADgxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMSUVQB2dHTEnDlzoqamJhoaGmL79u1vefyGDRvi/e9/f5x55pmRz+dj1apV8cc//rFI0wIAlEbZBOCWLVuitbU12traYufOnTF37txobm6O1157bdzjH3vssVi9enW0tbXF7t274+GHH44tW7bEbbfdVuTJAQCKq2wC8P77748bbrghVqxYER/84Adj48aNcdZZZ8Ujjzwy7vHPPfdcXHHFFXHdddfFnDlz4mMf+1hce+21f/GqIQDAO11ZBODw8HDs2LEjmpqaCmuVlZXR1NQUPT09455z+eWXx44dOwrBt3fv3ujs7Iyrr766KDMDAJTKlFIPMBkOHjwYIyMjUV9fP2a9vr4+9uzZM+451113XRw8eDA++tGPRpZlcfTo0bjpppve8iXgoaGhGBoaKvw8ODg4OQ8AAKCIyuIK4MnYtm1brFu3Lh588MHYuXNnPPHEE7F169a4++67j3tOe3t71NXVFW75fL6IEwMATI6KLMuyUg/xdg0PD8dZZ50Vjz/+eCxZsqSwvnz58jh06FD8x3/8xzHnLFq0KD7ykY/E17/+9cLav/3bv8WNN94Yv//976Oy8tg2Hu8KYD6fj4GBgaitrZ3cBwUAnBKDg4NRV1eX9PN3WVwBrK6ujvnz50d3d3dhbXR0NLq7u6OxsXHcc15//fVjIq+qqioiIo7XxLlcLmpra8fcAADeacriPYAREa2trbF8+fJYsGBBLFy4MDZs2BBHjhyJFStWRETEsmXLYvbs2dHe3h4REYsXL477778/Lr300mhoaIiXX3457rzzzli8eHEhBAEAylHZBGBLS0scOHAg1q5dG319fTFv3rzo6uoqfDBk3759Y6743XHHHVFRURF33HFH/PrXv473vOc9sXjx4vjqV79aqocAAFAUZfEewFLxHgIAeOfx/F0m7wEEAODECUAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxJRVAHZ0dMScOXOipqYmGhoaYvv27W95/KFDh2LlypUxc+bMyOVyccEFF0RnZ2eRpgUAKI0ppR5gsmzZsiVaW1tj48aN0dDQEBs2bIjm5uZ48cUXY/r06cccPzw8HH//938f06dPj8cffzxmz54dv/rVr+Kcc84p/vAAAEVUkWVZVuohJkNDQ0Ncdtll8cADD0RExOjoaOTz+bj55ptj9erVxxy/cePG+PrXvx579uyJM84446Tuc3BwMOrq6mJgYCBqa2vf1vwAQHF4/i6Tl4CHh4djx44d0dTUVFirrKyMpqam6OnpGfec73//+9HY2BgrV66M+vr6uOiii2LdunUxMjJy3PsZGhqKwcHBMTcA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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Animation dfs_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot.show_animation()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "97f390cd18944d49b735b4c5fb4ab84e",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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jRoVjz76aFx//fUD64sWLYqDBw/G3/7t3x5zzuzZs+M3f/M347777htY+8u//Mu46aab4s0334zi4mPbeKgrgNXV1dHd3R0VFRVn9kEBAGdFT09PVFZWJv38XRBXAEtLS2P69OnR1tY2sNbf3x9tbW1RV1c35DlvvfXWMZFXUlISERHHa+KysrKoqKgYdAMAON8UxHsAIyIaGxtj0aJFMWPGjJg5c2asWbMmDh8+HIsXL46IiIULF8bkyZOjubk5IiLmzp0bq1evjquvvjpqa2vjhRdeiLvuuivmzp07EIIAAIWoYAJw3rx5sX///lixYkV0dnbGtGnTorW1deAHQ/bu3Tvoit+dd94ZRUVFceedd8YvfvGLuOiii2Lu3Lnx9a9/PV8PAQAgJwriPYD54j0EAHD+8fxdIO8BBADg5AlAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQUVAC2tLRETU1NlJeXR21tbWzbtu2Exx88eDCWLFkSEydOjLKysrjssstiy5YtOZoWACA/RuR7gDNl48aN0djYGGvXro3a2tpYs2ZNNDQ0xO7du2P8+PHHHN/b2xsf//jHY/z48fHoo4/G5MmT45VXXokxY8bkfngAgBwqyrIsy/cQZ0JtbW189KMfjQceeCAiIvr7+6O6ujq+8IUvxLJly445fu3atXHffffFrl27YuTIkad0nz09PVFZWRnd3d1RUVFxWvMDALnh+btAXgLu7e2N7du3R319/cBacXFx1NfXR3t7+5Dn/OhHP4q6urpYsmRJVFVVxZVXXhkrV66Mvr6+497PkSNHoqenZ9ANAOB8UxABeODAgejr64uqqqpB61VVVdHZ2TnkOXv27IlHH300+vr6YsuWLXHXXXfFN77xjfja17523Ptpbm6OysrKgVt1dfUZfRwAALlQEAF4Kvr7+2P8+PHx7W9/O6ZPnx7z5s2LO+64I9auXXvcc5YvXx7d3d0Dt3379uVwYgCAM6Mgfghk3LhxUVJSEl1dXYPWu7q6YsKECUOeM3HixBg5cmSUlJQMrH3wgx+Mzs7O6O3tjdLS0mPOKSsri7KysjM7PABAjhXEFcDS0tKYPn16tLW1Daz19/dHW1tb1NXVDXnOrFmz4oUXXoj+/v6Bteeffz4mTpw4ZPwBABSKggjAiIjGxsZYt25dfO9734udO3fGLbfcEocPH47FixdHRMTChQtj+fLlA8ffcsst8cYbb8Rtt90Wzz//fGzevDlWrlwZS5YsyddDAADIiYJ4CTgiYt68ebF///5YsWJFdHZ2xrRp06K1tXXgB0P27t0bxcX/17vV1dXx+OOPx9KlS+Oqq66KyZMnx2233Ra33357vh4CAEBOFMznAOaDzxECgPOP5+8CegkYAICTIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAElNQAdjS0hI1NTVRXl4etbW1sW3btpM6b8OGDVFUVBTXX3/92R0QAOAcUDABuHHjxmhsbIympqbYsWNHTJ06NRoaGuL1118/4Xkvv/xy/PEf/3HMnj07R5MCAORXwQTg6tWr48Ybb4zFixfHFVdcEWvXro1Ro0bF+vXrj3tOX19ffPazn4277747Lr300hxOCwCQPwURgL29vbF9+/aor68fWCsuLo76+vpob28/7nlf/epXY/z48XHDDTec1P0cOXIkenp6Bt0AAM43BRGABw4ciL6+vqiqqhq0XlVVFZ2dnUOe89RTT8VDDz0U69atO+n7aW5ujsrKyoFbdXX1ac0NAJAPBRGAw3Xo0KFYsGBBrFu3LsaNG3fS5y1fvjy6u7sHbvv27TuLUwIAnB0j8j3AmTBu3LgoKSmJrq6uQetdXV0xYcKEY45/8cUX4+WXX465c+cOrPX390dExIgRI2L37t0xZcqUY84rKyuLsrKyMzw9AEBuFcQVwNLS0pg+fXq0tbUNrPX390dbW1vU1dUdc/zll18ezz77bHR0dAzcPvWpT8W1114bHR0dXtoFAApaQVwBjIhobGyMRYsWxYwZM2LmzJmxZs2aOHz4cCxevDgiIhYuXBiTJ0+O5ubmKC8vjyuvvHLQ+WPGjImIOGYdAKDQFEwAzps3L/bv3x8rVqyIzs7OmDZtWrS2tg78YMjevXujuLggLngCAJyWoizLsnwPcb7q6emJysrK6O7ujoqKinyPAwCcBM/fBfIeQAAATp4ABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEhMQQVgS0tL1NTURHl5edTW1sa2bduOe+y6deti9uzZMXbs2Bg7dmzU19ef8HgAgEJRMAG4cePGaGxsjKamptixY0dMnTo1Ghoa4vXXXx/y+K1bt8ZnPvOZ+OlPfxrt7e1RXV0dn/jEJ+IXv/hFjicHAMitoizLsnwPcSbU1tbGRz/60XjggQciIqK/vz+qq6vjC1/4Qixbtuw9z+/r64uxY8fGAw88EAsXLjyp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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map dijkstra_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, dijkstra_pro)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "ac70819630ef47acb2c2a6837c293e5a",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAevklEQVR4nO3df2zfdZ3A8Vfb0W8h0jJvrvtxX9yBh6jAhhurBRfCpWcTyLz9cbEHZpsLgugk3JpTNn6sIrpOBLJEigsTDpOT25QAZ1xTDnsuBqlZ3NYEZYPgwO2MLdvp2jm0Ze3n/rjw9eo6XEf3/Y7v+/FIvn/0zeez7+vLm/J95vP9sYosy7IAACAZlaUeAACA4hKAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiSmbAPzxj38cixcvjlmzZkVFRUU89dRTf/Gcbdu2xYc//OHI5XLxvve9Lx599NFTPicAQKmVTQAeOXIk5s6dGx0dHSd0/CuvvBLXXHNNXHXVVdHb2xv//M//HJ/+9Kfj6aefPsWTAgCUVkWWZVmph5hsFRUV8eSTT8aSJUuOe8ytt94aW7dujZ///OeFtX/6p3+KQ4cORVdXVxGmBAAojbK5AjhRPT090dTUNGatubk5enp6SjQRAEBxTCn1AKXS19cX9fX1Y9bq6+tjcHAw/vCHP8SZZ555zDlDQ0MxNDRU+Hl0dDR++9vfxl/91V9FRUXFKZ8ZAHj7siyLw4cPx6xZs6KyMs1rYckG4Mlob2+Pu+66q9RjAACTYP/+/fHXf/3XpR6jJJINwBkzZkR/f/+Ytf7+/qitrR336l9ExJo1a6K1tbXw88DAQJx77rmxf//+qK2tPaXzAgCTY3BwMPL5fJx99tmlHqVkkg3AxsbG6OzsHLP2zDPPRGNj43HPyeVykcvljlmvra0VgADwDpPy27fK5oXv3//+99Hb2xu9vb0R8X9f89Lb2xv79u2LiP+7erds2bLC8TfddFPs3bs3vvjFL8aePXviwQcfjO9+97uxatWqUowPAFA0ZROAP/vZz+LSSy+NSy+9NCIiWltb49JLL421a9dGRMRvfvObQgxGRPzN3/xNbN26NZ555pmYO3du3HffffGtb30rmpubSzI/AECxlOX3ABbL4OBg1NXVxcDAgJeAAeAdwvN3GV0BBADgxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMSUVQB2dHTEnDlzoqamJhoaGmL79u1vefyGDRvi/e9/f5x55pmRz+dj1apV8cc//rFI0wIAlEbZBOCWLVuitbU12traYufOnTF37txobm6O1157bdzjH3vssVi9enW0tbXF7t274+GHH44tW7bEbbfdVuTJAQCKq2wC8P77748bbrghVqxYER/84Adj48aNcdZZZ8Ujjzwy7vHPPfdcXHHFFXHdddfFnDlz4mMf+1hce+21f/GqIQDAO11ZBODw8HDs2LEjmpqaCmuVlZXR1NQUPT09455z+eWXx44dOwrBt3fv3ujs7Iyrr766KDMDAJTKlFIPMBkOHjwYIyMjUV9fP2a9vr4+9uzZM+451113XRw8eDA++tGPRpZlcfTo0bjpppve8iXgoaGhGBoaKvw8ODg4OQ8AAKCIyuIK4MnYtm1brFu3Lh588MHYuXNnPPHEE7F169a4++67j3tOe3t71NXVFW75fL6IEwMATI6KLMuyUg/xdg0PD8dZZ50Vjz/+eCxZsqSwvnz58jh06FD8x3/8xzHnLFq0KD7ykY/E17/+9cLav/3bv8WNN94Yv//976Oy8tg2Hu8KYD6fj4GBgaitrZ3cBwUAnBKDg4NRV1eX9PN3WVwBrK6ujvnz50d3d3dhbXR0NLq7u6OxsXHcc15//fVjIq+qqioiIo7XxLlcLmpra8fcAADeacriPYAREa2trbF8+fJYsGBBLFy4MDZs2BBHjhyJFStWRETEsmXLYvbs2dHe3h4REYsXL477778/Lr300mhoaIiXX3457rzzzli8eHEhBAEAylHZBGBLS0scOHAg1q5dG319fTFv3rzo6uoqfDBk3759Y6743XHHHVFRURF33HFH/PrXv473vOc9sXjx4vjqV79aqocAAFAUZfEewFLxHgIAeOfx/F0m7wEEAODECUAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxJRVAHZ0dMScOXOipqYmGhoaYvv27W95/KFDh2LlypUxc+bMyOVyccEFF0RnZ2eRpgUAKI0ppR5gsmzZsiVaW1tj48aN0dDQEBs2bIjm5uZ48cUXY/r06cccPzw8HH//938f06dPj8cffzxmz54dv/rVr+Kcc84p/vAAAEVUkWVZVuohJkNDQ0Ncdtll8cADD0RExOjoaOTz+bj55ptj9erVxxy/cePG+PrXvx579uyJM84446Tuc3BwMOrq6mJgYCBqa2vf1vwAQHF4/i6Tl4CHh4djx44d0dTUVFirrKyMpqam6OnpGfec73//+9HY2BgrV66M+vr6uOiii2LdunUxMjJy3PsZGhqKwcHBMTcA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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Animation dijkstra_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot.show_animation()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "52c408cf037744979fe9814fd5f9d3cb",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "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jRoVjz76aFx//fUD64sWLYqDBw/G3/7t3x5zzuzZs+M3f/M347777htY+8u//Mu46aab4s0334zi4mPbeKgrgNXV1dHd3R0VFRVn9kEBAGdFT09PVFZWJv38XRBXAEtLS2P69OnR1tY2sNbf3x9tbW1RV1c35DlvvfXWMZFXUlISERHHa+KysrKoqKgYdAMAON8UxHsAIyIaGxtj0aJFMWPGjJg5c2asWbMmDh8+HIsXL46IiIULF8bkyZOjubk5IiLmzp0bq1evjquvvjpqa2vjhRdeiLvuuivmzp07EIIAAIWoYAJw3rx5sX///lixYkV0dnbGtGnTorW1deAHQ/bu3Tvoit+dd94ZRUVFceedd8YvfvGLuOiii2Lu3Lnx9a9/PV8PAQAgJwriPYD54j0EAHD+8fxdIO8BBADg5AlAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQUVAC2tLRETU1NlJeXR21tbWzbtu2Exx88eDCWLFkSEydOjLKysrjssstiy5YtOZoWACA/RuR7gDNl48aN0djYGGvXro3a2tpYs2ZNNDQ0xO7du2P8+PHHHN/b2xsf//jHY/z48fHoo4/G5MmT45VXXokxY8bkfngAgBwqyrIsy/cQZ0JtbW189KMfjQceeCAiIvr7+6O6ujq+8IUvxLJly445fu3atXHffffFrl27YuTIkad0nz09PVFZWRnd3d1RUVFxWvMDALnh+btAXgLu7e2N7du3R319/cBacXFx1NfXR3t7+5Dn/OhHP4q6urpYsmRJVFVVxZVXXhkrV66Mvr6+497PkSNHoqenZ9ANAOB8UxABeODAgejr64uqqqpB61VVVdHZ2TnkOXv27IlHH300+vr6YsuWLXHXXXfFN77xjfja17523Ptpbm6OysrKgVt1dfUZfRwAALlQEAF4Kvr7+2P8+PHx7W9/O6ZPnx7z5s2LO+64I9auXXvcc5YvXx7d3d0Dt3379uVwYgCAM6Mgfghk3LhxUVJSEl1dXYPWu7q6YsKECUOeM3HixBg5cmSUlJQMrH3wgx+Mzs7O6O3tjdLS0mPOKSsri7KysjM7PABAjhXEFcDS0tKYPn16tLW1Daz19/dHW1tb1NXVDXnOrFmz4oUXXoj+/v6Bteeffz4mTpw4ZPwBABSKggjAiIjGxsZYt25dfO9734udO3fGLbfcEocPH47FixdHRMTChQtj+fLlA8ffcsst8cYbb8Rtt90Wzz//fGzevDlWrlwZS5YsyddDAADIiYJ4CTgiYt68ebF///5YsWJFdHZ2xrRp06K1tXXgB0P27t0bxcX/17vV1dXx+OOPx9KlS+Oqq66KyZMnx2233Ra33357vh4CAEBOFMznAOaDzxECgPOP5+8CegkYAICTIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAElNQAdjS0hI1NTVRXl4etbW1sW3btpM6b8OGDVFUVBTXX3/92R0QAOAcUDABuHHjxmhsbIympqbYsWNHTJ06NRoaGuL1118/4Xkvv/xy/PEf/3HMnj07R5MCAORXwQTg6tWr48Ybb4zFixfHFVdcEWvXro1Ro0bF+vXrj3tOX19ffPazn4277747Lr300hxOCwCQPwURgL29vbF9+/aor68fWCsuLo76+vpob28/7nlf/epXY/z48XHDDTec1P0cOXIkenp6Bt0AAM43BRGABw4ciL6+vqiqqhq0XlVVFZ2dnUOe89RTT8VDDz0U69atO+n7aW5ujsrKyoFbdXX1ac0NAJAPBRGAw3Xo0KFYsGBBrFu3LsaNG3fS5y1fvjy6u7sHbvv27TuLUwIAnB0j8j3AmTBu3LgoKSmJrq6uQetdXV0xYcKEY45/8cUX4+WXX465c+cOrPX390dExIgRI2L37t0xZcqUY84rKyuLsrKyMzw9AEBuFcQVwNLS0pg+fXq0tbUNrPX390dbW1vU1dUdc/zll18ezz77bHR0dAzcPvWpT8W1114bHR0dXtoFAApaQVwBjIhobGyMRYsWxYwZM2LmzJmxZs2aOHz4cCxevDgiIhYuXBiTJ0+O5ubmKC8vjyuvvHLQ+WPGjImIOGYdAKDQFEwAzps3L/bv3x8rVqyIzs7OmDZtWrS2tg78YMjevXujuLggLngCAJyWoizLsnwPcb7q6emJysrK6O7ujoqKinyPAwCcBM/fBfIeQAAATp4ABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEhMQQVgS0tL1NTURHl5edTW1sa2bduOe+y6deti9uzZMXbs2Bg7dmzU19ef8HgAgEJRMAG4cePGaGxsjKamptixY0dMnTo1Ghoa4vXXXx/y+K1bt8ZnPvOZ+OlPfxrt7e1RXV0dn/jEJ+IXv/hFjicHAMitoizLsnwPcSbU1tbGRz/60XjggQciIqK/vz+qq6vjC1/4Qixbtuw9z+/r64uxY8fGAw88EAsXLjyp++zp6YnKysro7u6OioqK05ofAMgNz98FcgWwt7c3tm/fHvX19QNrxcXFUV9fH+3t7Sf1Pd56661455134n3ve99xjzly5Ej09PQMugEAnG8KIgAPHDgQfX19UVVVNWi9qqoqOjs7T+p73H777TFp0qRBEfmrmpubo7KycuBWXV19WnMDAORDQQTg6Vq1alVs2LAhNm3aFOXl5cc9bvny5dHd3T1w27dvXw6nBAA4M0bke4AzYdy4cVFSUhJdXV2D1ru6umLChAknPPf++++PVatWxU9+8pO46qqrTnhsWVlZlJWVnfa8AAD5VBBXAEtLS2P69OnR1tY2sNbf3x9tbW1RV1d33PPuvffeuOeee6K1tTVmzJiRi1EBAPKuIK4ARkQ0NjbGokWLYsaMGTFz5sxYs2ZNHD58OBYvXhwREQsXLozJkydHc3NzRET86Z/+aaxYsSIeeeSRqKmpGXiv4IUXXhgXXnhh3h4HAMDZVjABOG/evNi/f3+sWLEiOjs7Y9q0adHa2jrwgyF79+6N4uL/u+D5rW99K3p7e+P3fu/3Bn2fpqam+MpXvpLL0QEAcqpgPgcwH3yOEACcfzx/F8h7AAEAOHkCEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMSPyPUA+9ff3x6uvvhqjR4+OoqKiYZ/f09Mz6L/DlWVZHDp0KCZNmhTFxVocAMiNpAPw1Vdfjerq6tP+Pqf7Pfbt2xcXX3zxac8BAHAykg7A0aNHR0TEP/3TP8WFF16Y8/t/8803Y86cOQNzAADkQtIB+O7LvhdeeGFeAvBX5wAAyAVvPAMASIwABABIjAAEAEhM0u8BPFWvvfZa/MVf/EX87Gc/i4MHD8ZFF10Uv/3bvx1LliyJsWPH5ns8AIATEoDDtG/fvpg3b17U1NTE6tWr4+KLL47/+I//iPvuuy9+9rOfxcaNG2PMmDH5HhMA4Li8BDxMd999d4wcOTLWr18fM2fOjEmTJsWcOXPiu9/9bnR1dcWf/dmf5XtEAIATEoDDcPDgwXjqqadi/vz5UV5ePuhrF110UcydOzf+4R/+IbIsy9OEAADvTQAOwyuvvBJZlsWUKVOG/PqUKVOiu7s73njjjRxPBgBw8gTgKXCFDwA4nwnAYbjkkkuiqKgoXnzxxSG//uKLL0ZlZWW8733vy/FkAAAnTwAOw9ixY2PWrFnxyCOPxNtvvz3oa/v374+/+7u/i9/5nd/xq90AgHOaABymu+66K3p7e+OGG26If/mXf4nXXnstnnzyyfjc5z4XVVVVsXTp0nyPCABwQgUVgC0tLVFTUxPl5eVRW1sb27ZtO+HxmzZtGvZ91NTUxN/8zd9EdXV1fPGLX4yPf/zjsWLFiqitrY0NGzb4DEAA4JxXMB8EvXHjxmhsbIy1a9dGbW1trFmzJhoaGmL37t0xfvz4Y45/+umn43Of+9wp3dfkyZNj1apVpzsyAEBeFMwVwNWrV8eNN94YixcvjiuuuCLWrl0bo0aNivXr1w95/J//+Z9HfX19jqcEAMi/grgC2NvbG9u3b4/ly5cPrBUXF0d9fX20t7cPeU57e3vceuut8eMf/zhXYx5XT09PvkcAgGS8+7yb8se6FUQAHjhwIPr6+qKqqmrQelVVVezatWvIczo7O+Oiiy7KxXjvqbq6Ot8jAEBy/uu//isqKyvzPUZeFEQAnu/27dsXFRUV+R7jvNbT0xPV1dX+Ls8B9uLcYj/OHfbi3NHd3R2XXHJJ0p/bWxABOG7cuCgpKYmurq5B611dXTFhwoQhz5kwYULs378/F+O9p4qKCv8zOEP8XZ477MW5xX6cO+zFuaO4uGB+FGLYCuKRl5aWxvTp06OtrW1grb+/P9ra2qKurm7Ic+rq6mLr1q05mhAA4NxREFcAIyIaGxtj0aJFMWPGjJg5c2asWbMmDh8+HIsXL46IiIULF8bkyZOjubk5IiJuu+22mD17dkREvPnmm3mZ+d37TflNqABA7hVMAM6bNy/2798fK1asiM7Ozpg2bVq0trYO/GDI3r17B13qveaaa6KlpSVuueWWmDNnTr7GjoiIQ4cOJfsm1DOlrKwsmpqaoqysLN+jJM9enFvsx7nDXpw77EVEUZbw5af+/v549dVXY/To0Xn5/b1ZlsWhQ4di0qRJSb8PAQDIraQDEAAgRS47AQAkRgACACRGAAIAJEYAvoeWlpaoqamJ8vLyqK2tjW3btp3w+L/+67+Oyy+/PMrLy+PDH/5wbNmyJUeTFr7h7MW6deti9uzZMXbs2Bg7dmzU19e/595x8ob77+JdGzZsiKKiorj++uvP7oAJGe5eHDx4MJYsWRITJ06MsrKyuOyyy/x/6gwa7n6sWbMmPvCBD8QFF1wQ1dXVsXTp0nj77bdzNG3hevLJJ2Pu3LkxadKkKCoqih/+8Ifvec7WrVvjIx/5SJSVlcX73//+ePjhh8/6nHmVcVwbNmzISktLs/Xr12f//u//nt14443ZmDFjsq6uriGP//nPf56VlJRk9957b/bcc89ld955ZzZy5Mjs2WefzfHkhWe4ezF//vyspaUle+aZZ7KdO3dmf/AHf5BVVlZm//mf/5njyQvPcPfiXS+99FI2efLkbPbs2dnv/u7v5mbYAjfcvThy5Eg2Y8aM7Lrrrsueeuqp7KWXXsq2bt2adXR05HjywjTc/fj+97+flZWVZd///vezl156KXv88ceziRMnZkuXLs3x5IVny5Yt2R133JE99thjWURkmzZtOuHxe/bsyUaNGpU1NjZmzz33XPbNb34zKykpyVpbW3MzcB4IwBOYOXNmtmTJkoE/9/X1ZZMmTcqam5uHPP7Tn/509slPfnLQWm1tbfaHf/iHZ3XOFAx3L37V0aNHs9GjR2ff+973ztaIyTiVvTh69Gh2zTXXZN/5zneyRYsWCcAzZLh78a1vfSu79NJLs97e3lyNmJTh7seSJUuy3/qt3xq01tjYmM2aNeuszpmakwnAL33pS9mHPvShQWvz5s3LGhoazuJk+eUl4OPo7e2N7du3R319/cBacXFx1NfXR3t7+5DntLe3Dzo+IqKhoeG4x3NyTmUvftVbb70V77zzTtK/+PtMONW9+OpXvxrjx4+PG264IRdjJuFU9uJHP/pR1NXVxZIlS6KqqiquvPLKWLlyZfT19eVq7IJ1KvtxzTXXxPbt2wdeJt6zZ09s2bIlrrvuupzMzP9J8fm7YH4TyJl24MCB6OvrG/hNIu+qqqqKXbt2DXlOZ2fnkMd3dnaetTlTcCp78atuv/32mDRp0jH/wBmeU9mLp556Kh566KHo6OjIwYTpOJW92LNnT/zjP/5jfPazn40tW7bECy+8ELfeemu888470dTUlIuxC9ap7Mf8+fPjwIED8bGPfSyyLIujR4/GzTffHF/+8pdzMTL/z/Gev3t6euKXv/xlXHDBBXma7OxxBZCCt2rVqtiwYUNs2rQpysvL8z1OUg4dOhQLFiyIdevWxbhx4/I9TvL6+/tj/Pjx8e1vfzumT58e8+bNizvuuCPWrl2b79GStHXr1li5cmU8+OCDsWPHjnjsscdi8+bNcc899+R7NBLgCuBxjBs3LkpKSqKrq2vQeldXV0yYMGHIcyZMmDCs4zk5p7IX77r//vtj1apV8ZOf/CSuuuqqszlmEoa7Fy+++GK8/PLLMXfu3IG1/v7+iIgYMWJE7N69O6ZMmXJ2hy5Qp/LvYuLEiTFy5MgoKSkZWPvgBz8YnZ2d0dvbG6WlpWd15kJ2Kvtx1113xYIFC+Lzn/98RER8+MMfjsOHD8dNN90Ud9xxh18RmkPHe/6uqKgoyKt/Ea4AHldpaWlMnz492traBtb6+/ujra0t6urqhjynrq5u0PEREU888cRxj+fknMpeRETce++9cc8990Rra2vMmDEjF6MWvOHuxeWXXx7PPvtsdHR0DNw+9alPxbXXXhsdHR1RXV2dy/ELyqn8u5g1a1a88MILAxEeEfH888/HxIkTxd9pOpX9eOutt46JvHfjPPNbWnMqyefvfP8Uyrlsw4YNWVlZWfbwww9nzz33XHbTTTdlY8aMyTo7O7Msy7IFCxZky5YtGzj+5z//eTZixIjs/vvvz3bu3Jk1NTX5GJgzZLh7sWrVqqy0tDR79NFHs9dee23gdujQoXw9hIIx3L34VX4K+MwZ7l7s3bs3Gz16dPZHf/RH2e7du7O///u/z8aPH5997Wtfy9dDKCjD3Y+mpqZs9OjR2V/91V9le/bsyX784x9nU6ZMyT796U/n6yEUjEOHDmXPPPNM9swzz2QRka1evTp75plnsldeeSXLsixbtmxZtmDBgoHj3/0YmD/5kz/Jdu7cmbW0tPgYmNR985vfzC655JKstLQ0mzlzZvbP//zPA1+bM2dOtmjRokHH/+AHP8guu+yyrLS0NPvQhz6Ubd68OccTF67h7MWv//qvZxFxzK2pqSn3gxeg4f67+P8E4Jk13L14+umns9ra2qysrCy79NJLs69//evZ0aNHczx14RrOfrzzzjvZV77ylWzKlClZeXl5Vl1dnd16663Zf//3f+d+8ALz05/+dMjngHf//hctWpTNmTPnmHOmTZuWlZaWZpdeemn23e9+N+dz51JRlrnODACQEu8BBABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIjAAEAEiMAAQASIwABABIzP8Aaug2NonrhygAAAAASUVORK5CYII=",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Map a_star_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot = PlotMap(map, a_star_pro)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9ef1f0b644cb4908aea71a2d0309ced6",
       "version_major": 2,
       "version_minor": 0
      },
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/H5lhTAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAevklEQVR4nO3df2zfdZ3A8Vfb0W8h0jJvrvtxX9yBh6jAhhurBRfCpWcTyLz9cbEHZpsLgugk3JpTNn6sIrpOBLJEigsTDpOT25QAZ1xTDnsuBqlZ3NYEZYPgwO2MLdvp2jm0Ze3n/rjw9eo6XEf3/Y7v+/FIvn/0zeez7+vLm/J95vP9sYosy7IAACAZlaUeAACA4hKAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiRGAAACJEYAAAIkRgAAAiSmbAPzxj38cixcvjlmzZkVFRUU89dRTf/Gcbdu2xYc//OHI5XLxvve9Lx599NFTPicAQKmVTQAeOXIk5s6dGx0dHSd0/CuvvBLXXHNNXHXVVdHb2xv//M//HJ/+9Kfj6aefPsWTAgCUVkWWZVmph5hsFRUV8eSTT8aSJUuOe8ytt94aW7dujZ///OeFtX/6p3+KQ4cORVdXVxGmBAAojbK5AjhRPT090dTUNGatubk5enp6SjQRAEBxTCn1AKXS19cX9fX1Y9bq6+tjcHAw/vCHP8SZZ555zDlDQ0MxNDRU+Hl0dDR++9vfxl/91V9FRUXFKZ8ZAHj7siyLw4cPx6xZs6KyMs1rYckG4Mlob2+Pu+66q9RjAACTYP/+/fHXf/3XpR6jJJINwBkzZkR/f/+Ytf7+/qitrR336l9ExJo1a6K1tbXw88DAQJx77rmxf//+qK2tPaXzAgCTY3BwMPL5fJx99tmlHqVkkg3AxsbG6OzsHLP2zDPPRGNj43HPyeVykcvljlmvra0VgADwDpPy27fK5oXv3//+99Hb2xu9vb0R8X9f89Lb2xv79u2LiP+7erds2bLC8TfddFPs3bs3vvjFL8aePXviwQcfjO9+97uxatWqUowPAFA0ZROAP/vZz+LSSy+NSy+9NCIiWltb49JLL421a9dGRMRvfvObQgxGRPzN3/xNbN26NZ555pmYO3du3HffffGtb30rmpubSzI/AECxlOX3ABbL4OBg1NXVxcDAgJeAAeAdwvN3GV0BBADgxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMSUVQB2dHTEnDlzoqamJhoaGmL79u1vefyGDRvi/e9/f5x55pmRz+dj1apV8cc//rFI0wIAlEbZBOCWLVuitbU12traYufOnTF37txobm6O1157bdzjH3vssVi9enW0tbXF7t274+GHH44tW7bEbbfdVuTJAQCKq2wC8P77748bbrghVqxYER/84Adj48aNcdZZZ8Ujjzwy7vHPPfdcXHHFFXHdddfFnDlz4mMf+1hce+21f/GqIQDAO11ZBODw8HDs2LEjmpqaCmuVlZXR1NQUPT09455z+eWXx44dOwrBt3fv3ujs7Iyrr766KDMDAJTKlFIPMBkOHjwYIyMjUV9fP2a9vr4+9uzZM+451113XRw8eDA++tGPRpZlcfTo0bjpppve8iXgoaGhGBoaKvw8ODg4OQ8AAKCIyuIK4MnYtm1brFu3Lh588MHYuXNnPPHEE7F169a4++67j3tOe3t71NXVFW75fL6IEwMATI6KLMuyUg/xdg0PD8dZZ50Vjz/+eCxZsqSwvnz58jh06FD8x3/8xzHnLFq0KD7ykY/E17/+9cLav/3bv8WNN94Yv//976Oy8tg2Hu8KYD6fj4GBgaitrZ3cBwUAnBKDg4NRV1eX9PN3WVwBrK6ujvnz50d3d3dhbXR0NLq7u6OxsXHcc15//fVjIq+qqioiIo7XxLlcLmpra8fcAADeacriPYAREa2trbF8+fJYsGBBLFy4MDZs2BBHjhyJFStWRETEsmXLYvbs2dHe3h4REYsXL477778/Lr300mhoaIiXX3457rzzzli8eHEhBAEAylHZBGBLS0scOHAg1q5dG319fTFv3rzo6uoqfDBk3759Y6743XHHHVFRURF33HFH/PrXv473vOc9sXjx4vjqV79aqocAAFAUZfEewFLxHgIAeOfx/F0m7wEEAODECUAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxAhAAIDECEAAgMQIQACAxJRVAHZ0dMScOXOipqYmGhoaYvv27W95/KFDh2LlypUxc+bMyOVyccEFF0RnZ2eRpgUAKI0ppR5gsmzZsiVaW1tj48aN0dDQEBs2bIjm5uZ48cUXY/r06cccPzw8HH//938f06dPj8cffzxmz54dv/rVr+Kcc84p/vAAAEVUkWVZVuohJkNDQ0Ncdtll8cADD0RExOjoaOTz+bj55ptj9erVxxy/cePG+PrXvx579uyJM84446Tuc3BwMOrq6mJgYCBqa2vf1vwAQHF4/i6Tl4CHh4djx44d0dTUVFirrKyMpqam6OnpGfec73//+9HY2BgrV66M+vr6uOiii2LdunUxMjJy3PsZGhqKwcHBMTcA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",
      "text/html": [
       "\n",
       "            <div style=\"display: inline-block;\">\n",
       "                <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
       "                    Animation a_star_pro\n",
       "                </div>\n",
       "                <img src='' width=640.0/>\n",
       "            </div>\n",
       "        "
      ],
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot.show_animation()"
   ]
  }
 ],
 "metadata": {
  "kaggle": {
   "accelerator": "none",
   "dataSources": [],
   "dockerImageVersionId": 30646,
   "isGpuEnabled": false,
   "isInternetEnabled": false,
   "language": "python",
   "sourceType": "notebook"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
